示例#1
0
        internal int CalculateStandalonePdbStreamSize()
        {
            int result =
                PdbIdSize +                                                // PDB ID
                sizeof(int) +                                              // EntryPoint
                sizeof(long) +                                             // ReferencedTypeSystemTables
                BitArithmetic.CountBits(ExternalTablesMask) * sizeof(int); // External row counts

            Debug.Assert(result % StreamAlignment == 0);
            return(result);
        }
示例#2
0
        /// <summary>
        /// Creates PE header builder.
        /// </summary>
        /// <exception cref="ArgumentOutOfRangeException">
        /// <paramref name="fileAlignment"/> is not power of 2 between 512 and 64K, or
        /// <paramref name="sectionAlignment"/> not power of 2 or it's less than <paramref name="fileAlignment"/>.
        /// </exception>
        public PEHeaderBuilder(
            Machine machine                       = 0,
            int sectionAlignment                  = 0x2000,
            int fileAlignment                     = 0x200,
            ulong imageBase                       = 0x00400000,
            byte majorLinkerVersion               = 0x30, // (what is ref.emit using?)
            byte minorLinkerVersion               = 0,
            ushort majorOperatingSystemVersion    = 4,
            ushort minorOperatingSystemVersion    = 0,
            ushort majorImageVersion              = 0,
            ushort minorImageVersion              = 0,
            ushort majorSubsystemVersion          = 4,
            ushort minorSubsystemVersion          = 0,
            Subsystem subsystem                   = Subsystem.WindowsCui,
            DllCharacteristics dllCharacteristics = DllCharacteristics.DynamicBase | DllCharacteristics.NxCompatible | DllCharacteristics.NoSeh | DllCharacteristics.TerminalServerAware,
            Characteristics imageCharacteristics  = Characteristics.Dll,
            ulong sizeOfStackReserve              = 0x00100000,
            ulong sizeOfStackCommit               = 0x1000,
            ulong sizeOfHeapReserve               = 0x00100000,
            ulong sizeOfHeapCommit                = 0x1000)
        {
            if (fileAlignment < 512 || fileAlignment > 64 * 1024 || BitArithmetic.CountBits(fileAlignment) != 1)
            {
                Throw.ArgumentOutOfRange(nameof(fileAlignment));
            }

            if (sectionAlignment < fileAlignment || BitArithmetic.CountBits(sectionAlignment) != 1)
            {
                Throw.ArgumentOutOfRange(nameof(sectionAlignment));
            }

            Machine                     = machine;
            SectionAlignment            = sectionAlignment;
            FileAlignment               = fileAlignment;
            ImageBase                   = imageBase;
            MajorLinkerVersion          = majorLinkerVersion;
            MinorLinkerVersion          = minorLinkerVersion;
            MajorOperatingSystemVersion = majorOperatingSystemVersion;
            MinorOperatingSystemVersion = minorOperatingSystemVersion;
            MajorImageVersion           = majorImageVersion;
            MinorImageVersion           = minorImageVersion;
            MajorSubsystemVersion       = majorSubsystemVersion;
            MinorSubsystemVersion       = minorSubsystemVersion;
            Subsystem                   = subsystem;
            DllCharacteristics          = dllCharacteristics;
            ImageCharacteristics        = imageCharacteristics;
            SizeOfStackReserve          = sizeOfStackReserve;
            SizeOfStackCommit           = sizeOfStackCommit;
            SizeOfHeapReserve           = sizeOfHeapReserve;
            SizeOfHeapCommit            = sizeOfHeapCommit;
        }
        public void ValidateTagToTokenConversion()
        {
            foreach (var tag in GetTags())
            {
                Assert.True((1 << tag.GetNumberOfBits()) <= tag.GetTagToTokenTypeArray().Length,
                            tag.Name + " has mismatch between NumberOfBits and TagToTokenTypeArray.Length");

                Assert.True(tag.GetTagMask() == (1 << tag.GetNumberOfBits()) - 1,
                            tag.Name + " has mismatch between NumberOfBits and TagMask");

                TableMask tablesNotUsed = tag.GetTablesReferenced();

                Assert.True(tablesNotUsed != 0,
                            tag.Name + " does not have anything in TablesReferenced.");

                int    badTagCount = 0;
                Random random      = new Random(42);

                for (uint i = 0, n = (uint)(1 << tag.GetNumberOfBits()); i < n; i++)
                {
                    uint rowId      = (uint)random.Next(((int)TokenTypeIds.RIDMask + 1));
                    uint codedIndex = i | (rowId << tag.GetNumberOfBits());

                    Handle handle;

                    try
                    {
                        handle = tag.ConvertToToken(codedIndex);
                    }
                    catch (BadImageFormatException)
                    {
                        badTagCount++;
                        continue;
                    }

                    Assert.True(handle.RowId == rowId,
                                tag.Name + " did not return correct row id.");

                    uint badRowId = (uint)random.Next((int)TokenTypeIds.RIDMask + 1, int.MaxValue);
                    Assert.Throws <BadImageFormatException>(() => tag.ConvertToToken(i | ~tag.GetTagMask()));
                    Assert.Throws <BadImageFormatException>(() => tag.ConvertToToken(i | ((TokenTypeIds.RIDMask + 1) << tag.GetNumberOfBits())));
                    Assert.Throws <BadImageFormatException>(() => tag.ConvertToToken(i | (badRowId << tag.GetNumberOfBits())));

                    Assert.True((uint)(handle.Kind) << 24 == tag.GetTagToTokenTypeArray()[i],
                                tag.Name + " did not return handle type matching its TagToTokenTypeArray or TagToTokenTypeByteVector");

                    TableMask handleTableMask = (TableMask)(1UL << (int)handle.Kind);

                    Assert.True(tag.GetTagValue(handleTableMask.ToString()) == i,
                                tag.Name + " does not have a constant for '" + handleTableMask.ToString() + "' with matching value: " + i);

                    Assert.True((tag.GetTablesReferenced() & handleTableMask) == handleTableMask,
                                tag.Name + " does not declare that it references '" + handleTableMask.ToString() + "' table.");

                    TableMask tablesNotUsedPreviously = tablesNotUsed;
                    tablesNotUsed &= ~handleTableMask;

                    Assert.True(handleTableMask == 0 || tablesNotUsedPreviously != tablesNotUsed,
                                tag.Name + " did not use any table for tag value: " + i);

                    uint?roundTripped = tag.ConvertToTag(handle);
                    Assert.True(roundTripped == null || roundTripped == codedIndex,
                                tag.Name + " did not round trip coded index -> handle -> coded index");
                }

                Assert.True(badTagCount == (1 << tag.GetNumberOfBits()) - BitArithmetic.CountBits((ulong)tag.GetTablesReferenced()),
                            tag.Name + " did not find the correct number of bad tags.");

                Assert.True(tablesNotUsed == 0,
                            tag.Name + " did not use all of TablesReferenced when passed all possible tag bits up to NumberOfBits.");
            }
        }
 // Helper methods
 internal int GetNumberOfTablesPresent()
 {
     return(BitArithmetic.CountBits((ulong)this.ValidTables));
 }