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); }
/// <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)); }