From cb9516da9df966079e5a34490139eec68c38dafa Mon Sep 17 00:00:00 2001 From: "jiseob.jang" Date: Wed, 6 Sep 2017 20:40:24 +0900 Subject: Imported Upstream version 2.0.0.12082 --- src/CMakeLists.txt | 8 +- src/debug/createdump/crashinfo.cpp | 522 +++++++++++++++++---- src/debug/createdump/crashinfo.h | 16 +- src/debug/createdump/createdump.h | 4 +- src/debug/createdump/dumpwriter.cpp | 65 +-- src/debug/createdump/dumpwriter.h | 6 - src/debug/createdump/memoryregion.h | 71 ++- src/debug/createdump/threadinfo.cpp | 22 +- src/jit/lower.cpp | 10 +- src/jit/morph.cpp | 115 ++++- src/mscorlib/System.Private.CoreLib.csproj | 1 - src/mscorlib/shared/System/Char.cs | 1 + .../shared/System/Collections/DictionaryEntry.cs | 5 +- .../System/Collections/Generic/KeyValuePair.cs | 5 +- src/mscorlib/shared/System/DateTime.cs | 5 +- src/mscorlib/shared/System/DateTimeOffset.cs | 9 +- .../shared/System/Globalization/SortVersion.cs | 1 + src/mscorlib/shared/System/Reflection/Assembly.cs | 5 +- src/mscorlib/shared/System/Reflection/Module.cs | 5 +- .../shared/System/Reflection/ParameterInfo.cs | 41 +- src/mscorlib/shared/System/StringComparer.cs | 137 +++++- src/mscorlib/shared/System/Text/StringBuilder.cs | 10 +- src/mscorlib/shared/System/ValueTuple.cs | 9 + src/mscorlib/shared/System/Version.cs | 9 +- src/mscorlib/src/System/AggregateException.cs | 3 +- src/mscorlib/src/System/Array.cs | 1 + src/mscorlib/src/System/ArraySegment.cs | 7 +- src/mscorlib/src/System/Attribute.cs | 1 + src/mscorlib/src/System/Boolean.cs | 1 + src/mscorlib/src/System/Byte.cs | 1 + src/mscorlib/src/System/Collections/Comparer.cs | 11 +- .../src/System/Collections/Generic/Comparer.cs | 8 + .../src/System/Collections/Generic/Dictionary.cs | 9 +- .../System/Collections/Generic/EqualityComparer.cs | 10 + .../src/System/Collections/Generic/List.cs | 7 +- .../System/Collections/ListDictionaryInternal.cs | 7 +- .../System/Collections/ObjectModel/Collection.cs | 3 +- .../Collections/ObjectModel/ReadOnlyCollection.cs | 3 +- src/mscorlib/src/System/Decimal.cs | 4 +- src/mscorlib/src/System/Double.cs | 1 + src/mscorlib/src/System/Enum.cs | 1 + src/mscorlib/src/System/Exception.cs | 49 +- .../System/Globalization/CompareInfo.Windows.cs | 1 + .../src/System/Globalization/CompareInfo.cs | 29 +- .../src/System/Globalization/CultureInfo.cs | 47 +- src/mscorlib/src/System/Guid.cs | 23 +- src/mscorlib/src/System/Int16.cs | 1 + src/mscorlib/src/System/Int32.cs | 1 + src/mscorlib/src/System/Int64.cs | 1 + src/mscorlib/src/System/IntPtr.cs | 3 +- src/mscorlib/src/System/Nullable.cs | 5 +- src/mscorlib/src/System/Object.cs | 1 + .../src/System/Reflection/Assembly.CoreCLR.cs | 14 +- .../Resources/LooselyLinkedResourceReference.cs | 85 ---- src/mscorlib/src/System/SByte.cs | 1 + src/mscorlib/src/System/Single.cs | 1 + src/mscorlib/src/System/String.cs | 1 + src/mscorlib/src/System/TimeSpan.cs | 2 +- .../src/System/TimeZoneInfo.AdjustmentRule.cs | 28 +- .../src/System/TimeZoneInfo.TransitionTime.cs | 24 +- src/mscorlib/src/System/TimeZoneInfo.cs | 29 +- src/mscorlib/src/System/Tuple.cs | 80 ++-- src/mscorlib/src/System/UInt16.cs | 1 + src/mscorlib/src/System/UInt32.cs | 1 + src/mscorlib/src/System/UInt64.cs | 1 + src/mscorlib/src/System/UIntPtr.cs | 3 +- src/mscorlib/src/System/ValueType.cs | 1 + src/mscorlib/src/System/WeakReference.cs | 9 +- src/mscorlib/src/System/WeakReferenceOfT.cs | 9 +- src/mscorlib/src/mscorlib.Friends.cs | 2 + src/pal/src/exception/seh-unwind.cpp | 9 +- src/pal/src/exception/signal.cpp | 36 +- src/pal/src/thread/process.cpp | 4 + src/pal/tools/gen-buildsys-clang.sh | 2 +- src/scripts/genEventPipe.py | 2 + src/vm/gcenv.ee.cpp | 7 +- src/vm/object.cpp | 3 +- 77 files changed, 1168 insertions(+), 508 deletions(-) delete mode 100644 src/mscorlib/src/System/Resources/LooselyLinkedResourceReference.cs (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b761b6a82d..d8a3abf68d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -53,9 +53,15 @@ else() ) endif(WIN32) +if(CLR_CMAKE_WARNINGS_ARE_ERRORS) + set(PYTHON_WARNING_FLAGS -Wall -Werror) +else() + set(PYTHON_WARNING_FLAGS -Wall) +endif(CLR_CMAKE_WARNINGS_ARE_ERRORS) + add_custom_command( COMMENT "Generating Eventing Files" - COMMAND ${PYTHON} -B -Wall -Werror ${GenEventFilesScript} ${GenEventArgs} --man "${VM_DIR}/ClrEtwAll.man" --exc "${VM_DIR}/ClrEtwAllMeta.lst" --dummy "${GENERATED_INCLUDE_DIR}/etmdummy.h" + COMMAND ${PYTHON} -B ${PYTHON_WARNING_FLAGS} ${GenEventFilesScript} ${GenEventArgs} --man "${VM_DIR}/ClrEtwAll.man" --exc "${VM_DIR}/ClrEtwAllMeta.lst" --dummy "${GENERATED_INCLUDE_DIR}/etmdummy.h" OUTPUT ${ScriptGeneratedEventFiles} DEPENDS ${GenEventFilesScript} "${VM_DIR}/ClrEtwAll.man" "${VM_DIR}/ClrEtwAllMeta.lst" "${CLR_DIR}/src/scripts/genXplatEventing.py" ) diff --git a/src/debug/createdump/crashinfo.cpp b/src/debug/createdump/crashinfo.cpp index b825f4d301..edc31616de 100644 --- a/src/debug/createdump/crashinfo.cpp +++ b/src/debug/createdump/crashinfo.cpp @@ -89,6 +89,10 @@ CrashInfo::EnumMemoryRegion( return S_OK; } +// +// Suspends all the threads and creating a list of them. Should be the first before +// gather any info about the process. +// bool CrashInfo::EnumerateAndSuspendThreads() { @@ -134,6 +138,9 @@ CrashInfo::EnumerateAndSuspendThreads() return true; } +// +// Gather all the necessary crash dump info. +// bool CrashInfo::GatherCrashInfo(const char* programPath, MINIDUMP_TYPE minidumpType) { @@ -168,42 +175,33 @@ CrashInfo::GatherCrashInfo(const char* programPath, MINIDUMP_TYPE minidumpType) // If full memory dump, include everything regardless of permissions if (minidumpType & MiniDumpWithFullMemory) { - for (const MemoryRegion& region : m_moduleMappings) - { - if (ValidRegion(region)) - { - InsertMemoryRegion(region); - } + for (const MemoryRegion& region : m_moduleMappings) + { + InsertMemoryBackedRegion(region); } for (const MemoryRegion& region : m_otherMappings) { - if (ValidRegion(region)) - { - InsertMemoryRegion(region); - } + InsertMemoryBackedRegion(region); } } - else + // Add all the heap (read/write) memory regions (m_otherMappings contains the heaps) + else if (minidumpType & MiniDumpWithPrivateReadWriteMemory) { - // Add all the heap (read/write) memory regions but not the modules' r/w data segments - if (minidumpType & MiniDumpWithPrivateReadWriteMemory) + for (const MemoryRegion& region : m_otherMappings) { - for (const MemoryRegion& region : m_otherMappings) + if (region.Permissions() == (PF_R | PF_W)) { - if (region.Permissions() == (PF_R | PF_W)) - { - if (ValidRegion(region)) - { - InsertMemoryRegion(region); - } - } + InsertMemoryBackedRegion(region); } } - // Gather all the useful memory regions from the DAC - if (!EnumerateMemoryRegionsWithDAC(programPath, minidumpType)) - { - return false; - } + } + // Gather all the useful memory regions from the DAC + if (!EnumerateMemoryRegionsWithDAC(programPath, minidumpType)) + { + return false; + } + if ((minidumpType & MiniDumpWithFullMemory) == 0) + { // Add the thread's stack and some code memory to core for (ThreadInfo* thread : m_threads) { @@ -217,6 +215,19 @@ CrashInfo::GatherCrashInfo(const char* programPath, MINIDUMP_TYPE minidumpType) thread->GetThreadCode(&start, &size); InsertMemoryRegion(start, size); } + // All the regions added so far has been backed by memory. Now add the rest of + // mappings so the debuggers like lldb see that an address is code (PF_X) even + // if it isn't actually in the core dump. + for (const MemoryRegion& region : m_moduleMappings) + { + assert(!region.IsBackedByMemory()); + InsertMemoryRegion(region); + } + for (const MemoryRegion& region : m_otherMappings) + { + assert(!region.IsBackedByMemory()); + InsertMemoryRegion(region); + } } // Join all adjacent memory regions CombineMemoryRegions(); @@ -235,6 +246,9 @@ CrashInfo::ResumeThreads() } } +// +// Get the auxv entries to use and add to the core dump +// bool CrashInfo::GetAuxvEntries() { @@ -269,6 +283,9 @@ CrashInfo::GetAuxvEntries() return result; } +// +// Get the module mappings for the core dump NT_FILE notes +// bool CrashInfo::EnumerateModuleMappings() { @@ -320,30 +337,38 @@ CrashInfo::EnumerateModuleMappings() int c = sscanf(line, "%lx-%lx %m[-rwxsp] %lx %*[:0-9a-f] %*d %ms\n", &start, &end, &permissions, &offset, &moduleName); if (c == 4 || c == 5) { - if (linuxGateAddress != nullptr && reinterpret_cast(start) == linuxGateAddress) - { - InsertMemoryRegion(start, end - start); - free(moduleName); + // r = read + // w = write + // x = execute + // s = shared + // p = private (copy on write) + uint32_t regionFlags = 0; + if (strchr(permissions, 'r')) { + regionFlags |= PF_R; } - else { - uint32_t permissionFlags = 0; - if (strchr(permissions, 'r')) { - permissionFlags |= PF_R; - } - if (strchr(permissions, 'w')) { - permissionFlags |= PF_W; - } - if (strchr(permissions, 'x')) { - permissionFlags |= PF_X; - } - MemoryRegion memoryRegion(permissionFlags, start, end, offset, moduleName); + if (strchr(permissions, 'w')) { + regionFlags |= PF_W; + } + if (strchr(permissions, 'x')) { + regionFlags |= PF_X; + } + if (strchr(permissions, 's')) { + regionFlags |= MEMORY_REGION_FLAG_SHARED; + } + if (strchr(permissions, 'p')) { + regionFlags |= MEMORY_REGION_FLAG_PRIVATE; + } + MemoryRegion memoryRegion(regionFlags, start, end, offset, moduleName); - if (moduleName != nullptr && *moduleName == '/') { - m_moduleMappings.insert(memoryRegion); - } - else { - m_otherMappings.insert(memoryRegion); - } + if (moduleName != nullptr && *moduleName == '/') { + m_moduleMappings.insert(memoryRegion); + } + else { + m_otherMappings.insert(memoryRegion); + } + if (linuxGateAddress != nullptr && reinterpret_cast(start) == linuxGateAddress) + { + InsertMemoryBackedRegion(memoryRegion); } free(permissions); } @@ -354,12 +379,12 @@ CrashInfo::EnumerateModuleMappings() TRACE("Module mappings:\n"); for (const MemoryRegion& region : m_moduleMappings) { - region.Print(); + region.Trace(); } TRACE("Other mappings:\n"); for (const MemoryRegion& region : m_otherMappings) { - region.Print(); + region.Trace(); } } @@ -369,12 +394,16 @@ CrashInfo::EnumerateModuleMappings() return true; } +// +// All the shared (native) module info to the core dump +// bool CrashInfo::GetDSOInfo() { Phdr* phdrAddr = reinterpret_cast(m_auxvValues[AT_PHDR]); int phnum = m_auxvValues[AT_PHNUM]; assert(m_auxvValues[AT_PHENT] == sizeof(Phdr)); + assert(phnum != PN_XNUM); if (phnum <= 0 || phdrAddr == nullptr) { return false; @@ -387,6 +416,7 @@ CrashInfo::GetDSOInfo() { Phdr ph; if (!ReadMemory(phdrAddr, &ph, sizeof(ph))) { + fprintf(stderr, "ReadMemory(%p, %lx) phdr FAILED\n", phdrAddr, sizeof(ph)); return false; } TRACE("DSO: phdr %p type %d (%x) vaddr %016lx memsz %016lx offset %016lx\n", @@ -396,7 +426,7 @@ CrashInfo::GetDSOInfo() { dynamicAddr = reinterpret_cast(ph.p_vaddr); } - else if (ph.p_type == PT_GNU_EH_FRAME) + else if (ph.p_type == PT_NOTE || ph.p_type == PT_GNU_EH_FRAME) { if (ph.p_vaddr != 0 && ph.p_memsz != 0) { @@ -414,6 +444,7 @@ CrashInfo::GetDSOInfo() for (;;) { ElfW(Dyn) dyn; if (!ReadMemory(dynamicAddr, &dyn, sizeof(dyn))) { + fprintf(stderr, "ReadMemory(%p, %lx) dyn FAILED\n", dynamicAddr, sizeof(dyn)); return false; } TRACE("DSO: dyn %p tag %ld (%lx) d_ptr %016lx\n", dynamicAddr, dyn.d_tag, dyn.d_tag, dyn.d_un.d_ptr); @@ -430,6 +461,7 @@ CrashInfo::GetDSOInfo() TRACE("DSO: rdebugAddr %p\n", rdebugAddr); struct r_debug debugEntry; if (!ReadMemory(rdebugAddr, &debugEntry, sizeof(debugEntry))) { + fprintf(stderr, "ReadMemory(%p, %lx) r_debug FAILED\n", rdebugAddr, sizeof(debugEntry)); return false; } @@ -438,8 +470,10 @@ CrashInfo::GetDSOInfo() for (struct link_map* linkMapAddr = debugEntry.r_map; linkMapAddr != nullptr;) { struct link_map map; if (!ReadMemory(linkMapAddr, &map, sizeof(map))) { + fprintf(stderr, "ReadMemory(%p, %lx) link_map FAILED\n", linkMapAddr, sizeof(map)); return false; } + // Read the module's name and make sure the memory is added to the core dump int i = 0; if (map.l_name != nullptr) { for (; i < PATH_MAX; i++) @@ -454,18 +488,134 @@ CrashInfo::GetDSOInfo() } } moduleName[i] = '\0'; - TRACE("DSO: link_map entry %p l_ld %p l_addr %lx %s\n", linkMapAddr, map.l_ld, map.l_addr, (char*)moduleName); + TRACE("\nDSO: link_map entry %p l_ld %p l_addr (Ehdr) %lx %s\n", linkMapAddr, map.l_ld, map.l_addr, (char*)moduleName); + + // Read the ELF header and info adding it to the core dump + if (!GetELFInfo(map.l_addr)) { + return false; + } linkMapAddr = map.l_next; } return true; } +inline bool +NameCompare(const char* name, const char* sectionName) +{ + return strncmp(name, sectionName, strlen(sectionName) + 1) == 0; +} + +// +// Add all the necessary ELF headers to the core dump +// +bool +CrashInfo::GetELFInfo(uint64_t baseAddress) +{ + if (baseAddress == 0) { + return true; + } + Ehdr ehdr; + if (!ReadMemory((void*)baseAddress, &ehdr, sizeof(ehdr))) { + fprintf(stderr, "ReadMemory(%p, %lx) ehdr FAILED\n", (void*)baseAddress, sizeof(ehdr)); + return false; + } + int phnum = ehdr.e_phnum; + int shnum = ehdr.e_shnum; + assert(phnum != PN_XNUM); + assert(shnum != SHN_XINDEX); + assert(ehdr.e_shstrndx != SHN_XINDEX); + assert(ehdr.e_phentsize == sizeof(Phdr)); + assert(ehdr.e_shentsize == sizeof(Shdr)); + assert(ehdr.e_ident[EI_CLASS] == ELFCLASS64); + assert(ehdr.e_ident[EI_DATA] == ELFDATA2LSB); + + TRACE("ELF: type %d mach 0x%x ver %d flags 0x%x phnum %d phoff %016lx phentsize 0x%02x shnum %d shoff %016lx shentsize 0x%02x shstrndx %d\n", + ehdr.e_type, ehdr.e_machine, ehdr.e_version, ehdr.e_flags, phnum, ehdr.e_phoff, ehdr.e_phentsize, shnum, ehdr.e_shoff, ehdr.e_shentsize, ehdr.e_shstrndx); + + if (ehdr.e_phoff != 0 && phnum > 0) + { + Phdr* phdrAddr = reinterpret_cast(baseAddress + ehdr.e_phoff); + + // Add the program headers and search for the module's note and unwind info segments + for (int i = 0; i < phnum; i++, phdrAddr++) + { + Phdr ph; + if (!ReadMemory(phdrAddr, &ph, sizeof(ph))) { + fprintf(stderr, "ReadMemory(%p, %lx) phdr FAILED\n", phdrAddr, sizeof(ph)); + return false; + } + TRACE("ELF: phdr %p type %d (%x) vaddr %016lx memsz %016lx paddr %016lx filesz %016lx offset %016lx align %016lx\n", + phdrAddr, ph.p_type, ph.p_type, ph.p_vaddr, ph.p_memsz, ph.p_paddr, ph.p_filesz, ph.p_offset, ph.p_align); + + if (ph.p_type == PT_DYNAMIC || ph.p_type == PT_NOTE || ph.p_type == PT_GNU_EH_FRAME) + { + if (ph.p_vaddr != 0 && ph.p_memsz != 0) + { + InsertMemoryRegion(baseAddress + ph.p_vaddr, ph.p_memsz); + } + } + } + } + + // Skip the "interpreter" module i.e. /lib64/ld-linux-x86-64.so.2 or ld-2.19.so. The in-memory section headers are + // not valid. Ignore all failures too because on debug builds of coreclr, the section headers are not in valid memory. + if (baseAddress != m_auxvValues[AT_BASE] && ehdr.e_shoff != 0 && shnum > 0 && ehdr.e_shstrndx != SHN_UNDEF) + { + Shdr* shdrAddr = reinterpret_cast(baseAddress + ehdr.e_shoff); + + // Get the string table section header + Shdr stringTableSectionHeader; + if (!ReadMemory(shdrAddr + ehdr.e_shstrndx, &stringTableSectionHeader, sizeof(stringTableSectionHeader))) { + TRACE("ELF: %2d shdr %p ReadMemory string table section header FAILED\n", ehdr.e_shstrndx, shdrAddr + ehdr.e_shstrndx); + return true; + } + // Get the string table + ArrayHolder stringTable = new char[stringTableSectionHeader.sh_size]; + if (!ReadMemory((void*)(baseAddress + stringTableSectionHeader.sh_offset), stringTable.GetPtr(), stringTableSectionHeader.sh_size)) { + TRACE("ELF: %2d shdr %p ReadMemory string table FAILED\n", ehdr.e_shstrndx, (void*)(baseAddress + stringTableSectionHeader.sh_offset)); + return true; + } + // Add the section headers to the core dump + for (int sectionIndex = 0; sectionIndex < shnum; sectionIndex++, shdrAddr++) + { + Shdr sh; + if (!ReadMemory(shdrAddr, &sh, sizeof(sh))) { + TRACE("ELF: %2d shdr %p ReadMemory FAILED\n", sectionIndex, shdrAddr); + return true; + } + TRACE("ELF: %2d shdr %p type %2d (%x) addr %016lx offset %016lx size %016lx link %08x info %08x name %4d %s\n", + sectionIndex, shdrAddr, sh.sh_type, sh.sh_type, sh.sh_addr, sh.sh_offset, sh.sh_size, sh.sh_link, sh.sh_info, sh.sh_name, &stringTable[sh.sh_name]); + + if (sh.sh_name != SHN_UNDEF && sh.sh_offset > 0 && sh.sh_size > 0) { + char* name = &stringTable[sh.sh_name]; + + // Add the .eh_frame/.eh_frame_hdr unwind info to the core dump + if (NameCompare(name, ".eh_frame") || + NameCompare(name, ".eh_frame_hdr") || + NameCompare(name, ".note.gnu.build-id") || + NameCompare(name, ".note.gnu.ABI-tag") || + NameCompare(name, ".gnu_debuglink")) + { + TRACE("ELF: %s %p size %016lx\n", name, (void*)(baseAddress + sh.sh_offset), sh.sh_size); + InsertMemoryRegion(baseAddress + sh.sh_offset, sh.sh_size); + } + } + } + } + + return true; +} + +// +// Enumerate all the memory regions using the DAC memory region support given a minidump type +// bool CrashInfo::EnumerateMemoryRegionsWithDAC(const char* programPath, MINIDUMP_TYPE minidumpType) { PFN_CLRDataCreateInstance pfnCLRDataCreateInstance = nullptr; - ICLRDataEnumMemoryRegions *clrDataEnumRegions = nullptr; + ICLRDataEnumMemoryRegions* clrDataEnumRegions = nullptr; + IXCLRDataProcess* clrDataProcess = nullptr; HMODULE hdac = nullptr; HRESULT hr = S_OK; bool result = false; @@ -475,7 +625,7 @@ CrashInfo::EnumerateMemoryRegionsWithDAC(const char* programPath, MINIDUMP_TYPE dacPath.append(programPath); dacPath.append("/"); dacPath.append(MAKEDLLNAME_A("mscordaccore")); - + // Load and initialize the DAC hdac = LoadLibraryA(dacPath.c_str()); if (hdac == nullptr) @@ -489,17 +639,30 @@ CrashInfo::EnumerateMemoryRegionsWithDAC(const char* programPath, MINIDUMP_TYPE fprintf(stderr, "GetProcAddress(CLRDataCreateInstance) FAILED %d\n", GetLastError()); goto exit; } - hr = pfnCLRDataCreateInstance(__uuidof(ICLRDataEnumMemoryRegions), m_dataTarget, (void**)&clrDataEnumRegions); + if ((minidumpType & MiniDumpWithFullMemory) == 0) + { + hr = pfnCLRDataCreateInstance(__uuidof(ICLRDataEnumMemoryRegions), m_dataTarget, (void**)&clrDataEnumRegions); + if (FAILED(hr)) + { + fprintf(stderr, "CLRDataCreateInstance(ICLRDataEnumMemoryRegions) FAILED %08x\n", hr); + goto exit; + } + // Calls CrashInfo::EnumMemoryRegion for each memory region found by the DAC + hr = clrDataEnumRegions->EnumMemoryRegions(this, minidumpType, CLRDATA_ENUM_MEM_DEFAULT); + if (FAILED(hr)) + { + fprintf(stderr, "EnumMemoryRegions FAILED %08x\n", hr); + goto exit; + } + } + hr = pfnCLRDataCreateInstance(__uuidof(IXCLRDataProcess), m_dataTarget, (void**)&clrDataProcess); if (FAILED(hr)) { - fprintf(stderr, "CLRDataCreateInstance(ICLRDataEnumMemoryRegions) FAILED %08x\n", hr); + fprintf(stderr, "CLRDataCreateInstance(IXCLRDataProcess) FAILED %08x\n", hr); goto exit; } - // Calls CrashInfo::EnumMemoryRegion for each memory region found by the DAC - hr = clrDataEnumRegions->EnumMemoryRegions(this, minidumpType, CLRDATA_ENUM_MEM_DEFAULT); - if (FAILED(hr)) + if (!EnumerateManagedModules(clrDataProcess)) { - fprintf(stderr, "EnumMemoryRegions FAILED %08x\n", hr); goto exit; } result = true; @@ -508,6 +671,10 @@ exit: { clrDataEnumRegions->Release(); } + if (clrDataProcess != nullptr) + { + clrDataProcess->Release(); + } if (hdac != nullptr) { FreeLibrary(hdac); @@ -515,6 +682,104 @@ exit: return result; } +// +// Enumerate all the managed modules and replace the module +// mapping with the module name found. +// +bool +CrashInfo::EnumerateManagedModules(IXCLRDataProcess* clrDataProcess) +{ + IXCLRDataModule* clrDataModule = nullptr; + CLRDATA_ENUM enumModules = 0; + HRESULT hr = S_OK; + + if (FAILED(hr = clrDataProcess->StartEnumModules(&enumModules))) { + fprintf(stderr, "StartEnumModules FAILED %08x\n", hr); + return false; + } + while ((hr = clrDataProcess->EnumModule(&enumModules, &clrDataModule)) == S_OK) + { + DacpGetModuleData moduleData; + if (SUCCEEDED(hr = moduleData.Request(clrDataModule))) + { + TRACE("MODULE: %016lx dyn %d inmem %d file %d pe %016lx pdb %016lx", moduleData.LoadedPEAddress, moduleData.IsDynamic, + moduleData.IsInMemory, moduleData.IsFileLayout, moduleData.PEFile, moduleData.InMemoryPdbAddress); + + if (!moduleData.IsDynamic && moduleData.LoadedPEAddress != 0) + { + ArrayHolder wszUnicodeName = new WCHAR[MAX_LONGPATH + 1]; + if (SUCCEEDED(hr = clrDataModule->GetFileName(MAX_LONGPATH, NULL, wszUnicodeName))) + { + char* pszName = (char*)malloc(MAX_LONGPATH + 1); + if (pszName == nullptr) { + fprintf(stderr, "Allocating module name FAILED\n"); + return false; + } + sprintf_s(pszName, MAX_LONGPATH, "%S", (WCHAR*)wszUnicodeName); + TRACE(" %s\n", pszName); + + // Change the module mapping name + ReplaceModuleMapping(moduleData.LoadedPEAddress, pszName); + } + else { + TRACE("\nModule.GetFileName FAILED %08x\n", hr); + } + } + else { + TRACE("\n"); + } + } + else { + TRACE("moduleData.Request FAILED %08x\n", hr); + } + if (clrDataModule != nullptr) { + clrDataModule->Release(); + } + } + if (enumModules != 0) { + clrDataProcess->EndEnumModules(enumModules); + } + return true; +} + +// +// Replace an existing module mapping with one with a different name. +// +void +CrashInfo::ReplaceModuleMapping(CLRDATA_ADDRESS baseAddress, const char* pszName) +{ + // Add or change the module mapping for this PE image. The managed assembly images are + // already in the module mappings list but in .NET 2.0 they have the name "/dev/zero". + MemoryRegion region(PF_R | PF_W | PF_X, baseAddress, baseAddress + PAGE_SIZE, 0, pszName); + const auto& found = m_moduleMappings.find(region); + if (found == m_moduleMappings.end()) + { + m_moduleMappings.insert(region); + + if (g_diagnostics) { + TRACE("MODULE: ADD "); + region.Trace(); + } + } + else + { + // Create the new memory region with the managed assembly name. + MemoryRegion newRegion(*found, pszName); + + // Remove and cleanup the old one + m_moduleMappings.erase(found); + const_cast(*found).Cleanup(); + + // Add the new memory region + m_moduleMappings.insert(newRegion); + + if (g_diagnostics) { + TRACE("MODULE: REPLACE "); + newRegion.Trace(); + } + } +} + // // ReadMemory from target and add to memory regions list // @@ -524,7 +789,6 @@ CrashInfo::ReadMemory(void* address, void* buffer, size_t size) uint32_t read = 0; if (FAILED(m_dataTarget->ReadVirtual(reinterpret_cast(address), reinterpret_cast(buffer), size, &read))) { - fprintf(stderr, "ReadMemory(%p, %lx) FAILED\n", address, size); return false; } InsertMemoryRegion(reinterpret_cast(address), size); @@ -538,6 +802,8 @@ CrashInfo::ReadMemory(void* address, void* buffer, size_t size) void CrashInfo::InsertMemoryRegion(uint64_t address, size_t size) { + assert(size < UINT_MAX); + // Round to page boundary uint64_t start = address & PAGE_MASK; assert(start > 0); @@ -546,8 +812,16 @@ CrashInfo::InsertMemoryRegion(uint64_t address, size_t size) uint64_t end = ((address + size) + (PAGE_SIZE - 1)) & PAGE_MASK; assert(end > 0); - MemoryRegion region(start, end); - InsertMemoryRegion(region); + InsertMemoryRegion(MemoryRegion(GetMemoryRegionFlags(start) | MEMORY_REGION_FLAG_MEMORY_BACKED, start, end)); +} + +// +// Adds a memory backed flagged copy of the memory region. The file name is not preserved. +// +void +CrashInfo::InsertMemoryBackedRegion(const MemoryRegion& region) +{ + InsertMemoryRegion(MemoryRegion(region, region.Flags() | MEMORY_REGION_FLAG_MEMORY_BACKED)); } // @@ -556,52 +830,88 @@ CrashInfo::InsertMemoryRegion(uint64_t address, size_t size) void CrashInfo::InsertMemoryRegion(const MemoryRegion& region) { - // First check if the full memory region can be added without conflicts + // First check if the full memory region can be added without conflicts and is fully valid. const auto& found = m_memoryRegions.find(region); if (found == m_memoryRegions.end()) { - // Add full memory region - m_memoryRegions.insert(region); + // If the region is valid, add the full memory region + if (ValidRegion(region)) { + m_memoryRegions.insert(region); + return; + } } else { - // The memory region is not wholely contained in region found - if (!found->Contains(region)) - { - uint64_t start = region.StartAddress(); + // If the memory region is wholly contained in region found and both have the + // same backed by memory state, we're done. + if (found->Contains(region) && (found->IsBackedByMemory() == region.IsBackedByMemory())) { + return; + } + } + // Either part of the region was invalid, part of it hasn't been added or the backed + // by memory state is different. + uint64_t start = region.StartAddress(); - // The region overlaps/conflicts with one already in the set so - // add one page at a time to avoid the overlapping pages. - uint64_t numberPages = region.Size() >> PAGE_SHIFT; + // The region overlaps/conflicts with one already in the set so add one page at a + // time to avoid the overlapping pages. + uint64_t numberPages = region.Size() >> PAGE_SHIFT; - for (int p = 0; p < numberPages; p++, start += PAGE_SIZE) - { - MemoryRegion memoryRegionPage(start, start + PAGE_SIZE); + for (int p = 0; p < numberPages; p++, start += PAGE_SIZE) + { + MemoryRegion memoryRegionPage(region.Flags(), start, start + PAGE_SIZE); - const auto& found = m_memoryRegions.find(memoryRegionPage); - if (found == m_memoryRegions.end()) - { - m_memoryRegions.insert(memoryRegionPage); - } + const auto& found = m_memoryRegions.find(memoryRegionPage); + if (found == m_memoryRegions.end()) + { + // All the single pages added here will be combined in CombineMemoryRegions() + if (ValidRegion(memoryRegionPage)) { + m_memoryRegions.insert(memoryRegionPage); } } + else { + assert(found->IsBackedByMemory() || !region.IsBackedByMemory()); + } } } +// +// Get the memory region flags for a start address +// +uint32_t +CrashInfo::GetMemoryRegionFlags(uint64_t start) +{ + const MemoryRegion* region = SearchMemoryRegions(m_moduleMappings, start); + if (region != nullptr) { + return region->Flags(); + } + region = SearchMemoryRegions(m_otherMappings, start); + if (region != nullptr) { + return region->Flags(); + } + TRACE("GetMemoryRegionFlags: FAILED\n"); + return PF_R | PF_W | PF_X; +} + +// +// Validates a memory region +// bool CrashInfo::ValidRegion(const MemoryRegion& region) { - uint64_t start = region.StartAddress(); - uint64_t numberPages = region.Size() >> PAGE_SHIFT; - - for (int p = 0; p < numberPages; p++, start += PAGE_SIZE) + if (region.IsBackedByMemory()) { - BYTE buffer[1]; - uint32_t read; + uint64_t start = region.StartAddress(); + uint64_t numberPages = region.Size() >> PAGE_SHIFT; - if (FAILED(m_dataTarget->ReadVirtual(start, buffer, 1, &read))) + for (int p = 0; p < numberPages; p++, start += PAGE_SIZE) { - return false; + BYTE buffer[1]; + uint32_t read; + + if (FAILED(m_dataTarget->ReadVirtual(start, buffer, 1, &read))) + { + return false; + } } } return true; @@ -617,28 +927,34 @@ CrashInfo::CombineMemoryRegions() std::set memoryRegionsNew; + // MEMORY_REGION_FLAG_SHARED and MEMORY_REGION_FLAG_PRIVATE are internal flags that + // don't affect the core dump so ignore them when comparing the flags. + uint32_t flags = m_memoryRegions.begin()->Flags() & (MEMORY_REGION_FLAG_MEMORY_BACKED | MEMORY_REGION_FLAG_PERMISSIONS_MASK); uint64_t start = m_memoryRegions.begin()->StartAddress(); uint64_t end = start; for (const MemoryRegion& region : m_memoryRegions) { - if (end == region.StartAddress()) + // To combine a region it needs to be contiguous, same permissions and memory backed flag. + if ((end == region.StartAddress()) && + (flags == (region.Flags() & (MEMORY_REGION_FLAG_MEMORY_BACKED | MEMORY_REGION_FLAG_PERMISSIONS_MASK)))) { end = region.EndAddress(); } else { - MemoryRegion memoryRegion(start, end); + MemoryRegion memoryRegion(flags, start, end); assert(memoryRegionsNew.find(memoryRegion) == memoryRegionsNew.end()); memoryRegionsNew.insert(memoryRegion); + flags = region.Flags() & (MEMORY_REGION_FLAG_MEMORY_BACKED | MEMORY_REGION_FLAG_PERMISSIONS_MASK); start = region.StartAddress(); end = region.EndAddress(); } } assert(start != end); - MemoryRegion memoryRegion(start, end); + MemoryRegion memoryRegion(flags, start, end); assert(memoryRegionsNew.find(memoryRegion) == memoryRegionsNew.end()); memoryRegionsNew.insert(memoryRegion); @@ -649,11 +965,31 @@ CrashInfo::CombineMemoryRegions() TRACE("Memory Regions:\n"); for (const MemoryRegion& region : m_memoryRegions) { - region.Print(); + region.Trace(); + } + } +} + +// +// Searches for a memory region given an address. +// +const MemoryRegion* +CrashInfo::SearchMemoryRegions(const std::set& regions, uint64_t start) +{ + std::set::iterator found = regions.find(MemoryRegion(0, start, start + PAGE_SIZE)); + for (; found != regions.end(); found++) + { + if (start >= found->StartAddress() && start < found->EndAddress()) + { + return &*found; } } + return nullptr; } +// +// Get the process or thread status +// bool CrashInfo::GetStatus(pid_t pid, pid_t* ppid, pid_t* tgid, char** name) { diff --git a/src/debug/createdump/crashinfo.h b/src/debug/createdump/crashinfo.h index 914a88e8dd..43e82691aa 100644 --- a/src/debug/createdump/crashinfo.h +++ b/src/debug/createdump/crashinfo.h @@ -38,6 +38,7 @@ public: bool GatherCrashInfo(const char* programPath, MINIDUMP_TYPE minidumpType); void ResumeThreads(); static bool GetStatus(pid_t pid, pid_t* ppid, pid_t* tgid, char** name); + static const MemoryRegion* SearchMemoryRegions(const std::set& regions, uint64_t start); const pid_t Pid() const { return m_pid; } const pid_t Ppid() const { return m_ppid; } @@ -46,9 +47,9 @@ public: ICLRDataTarget* DataTarget() const { return m_dataTarget; } const std::vector Threads() const { return m_threads; } - const std::set ModuleMappings() const { return m_moduleMappings; } - const std::set OtherMappings() const { return m_otherMappings; } - const std::set MemoryRegions() const { return m_memoryRegions; } + const std::set ModuleMappings() const { return m_moduleMappings; } + const std::set OtherMappings() const { return m_otherMappings; } + const std::set MemoryRegions() const { return m_memoryRegions; } const std::vector AuxvEntries() const { return m_auxvEntries; } const size_t GetAuxvSize() const { return m_auxvEntries.size() * sizeof(elf_aux_entry); } @@ -58,18 +59,21 @@ public: STDMETHOD_(ULONG, Release)(); // ICLRDataEnumMemoryRegionsCallback - virtual HRESULT STDMETHODCALLTYPE EnumMemoryRegion( - /* [in] */ CLRDATA_ADDRESS address, - /* [in] */ ULONG32 size); + virtual HRESULT STDMETHODCALLTYPE EnumMemoryRegion(/* [in] */ CLRDATA_ADDRESS address, /* [in] */ ULONG32 size); private: bool GetAuxvEntries(); bool EnumerateModuleMappings(); bool GetDSOInfo(); + bool GetELFInfo(uint64_t baseAddress); bool EnumerateMemoryRegionsWithDAC(const char* programPath, MINIDUMP_TYPE minidumpType); + bool EnumerateManagedModules(IXCLRDataProcess* clrDataProcess); + void ReplaceModuleMapping(CLRDATA_ADDRESS baseAddress, const char* pszName); bool ReadMemory(void* address, void* buffer, size_t size); + void InsertMemoryBackedRegion(const MemoryRegion& region); void InsertMemoryRegion(uint64_t address, size_t size); void InsertMemoryRegion(const MemoryRegion& region); + uint32_t GetMemoryRegionFlags(uint64_t start); bool ValidRegion(const MemoryRegion& region); void CombineMemoryRegions(); }; diff --git a/src/debug/createdump/createdump.h b/src/debug/createdump/createdump.h index 38c3525f34..6f72f0e955 100644 --- a/src/debug/createdump/createdump.h +++ b/src/debug/createdump/createdump.h @@ -33,6 +33,8 @@ extern bool g_diagnostics; #include #include #include +typedef int T_CONTEXT; +#include #include #include #include @@ -54,4 +56,4 @@ extern bool g_diagnostics; #include "threadinfo.h" #include "memoryregion.h" #include "crashinfo.h" -#include "dumpwriter.h" \ No newline at end of file +#include "dumpwriter.h" diff --git a/src/debug/createdump/dumpwriter.cpp b/src/debug/createdump/dumpwriter.cpp index 69f0ece8af..06c5b96d01 100644 --- a/src/debug/createdump/dumpwriter.cpp +++ b/src/debug/createdump/dumpwriter.cpp @@ -91,14 +91,9 @@ DumpWriter::WriteDump() ehdr.e_ident[1] = ELFMAG1; ehdr.e_ident[2] = ELFMAG2; ehdr.e_ident[3] = ELFMAG3; - ehdr.e_ident[4] = ELF_CLASS; - - // Note: The sex is the current system running minidump-2-core - // Big or Little endian. This means you have to create - // the core (minidump-2-core) on the system that matches - // your intent to debug properly. - ehdr.e_ident[5] = sex() ? ELFDATA2MSB : ELFDATA2LSB; - ehdr.e_ident[6] = EV_CURRENT; + ehdr.e_ident[EI_CLASS] = ELF_CLASS; + ehdr.e_ident[EI_DATA] = ELFDATA2LSB; + ehdr.e_ident[EI_VERSION] = EV_CURRENT; ehdr.e_ident[EI_OSABI] = ELFOSABI_LINUX; ehdr.e_type = ET_CORE; @@ -180,9 +175,17 @@ DumpWriter::WriteDump() phdr.p_vaddr = memoryRegion.StartAddress(); phdr.p_memsz = memoryRegion.Size(); - offset += filesz; - phdr.p_filesz = filesz = memoryRegion.Size(); - phdr.p_offset = offset; + if (memoryRegion.IsBackedByMemory()) + { + offset += filesz; + phdr.p_filesz = filesz = memoryRegion.Size(); + phdr.p_offset = offset; + } + else + { + phdr.p_filesz = 0; + phdr.p_offset = 0; + } if (!WriteData(&phdr, sizeof(phdr))) { return false; @@ -230,26 +233,30 @@ DumpWriter::WriteDump() uint64_t total = 0; for (const MemoryRegion& memoryRegion : m_crashInfo.MemoryRegions()) { - uint32_t size = memoryRegion.Size(); - uint64_t address = memoryRegion.StartAddress(); - total += size; - - while (size > 0) + // Only write the regions that are backed by memory + if (memoryRegion.IsBackedByMemory()) { - uint32_t bytesToRead = std::min(size, (uint32_t)sizeof(m_tempBuffer)); - uint32_t read = 0; - - if (FAILED(m_crashInfo.DataTarget()->ReadVirtual(address, m_tempBuffer, bytesToRead, &read))) { - fprintf(stderr, "ReadVirtual(%016lx, %08x) FAILED\n", address, bytesToRead); - return false; - } - - if (!WriteData(m_tempBuffer, read)) { - return false; + uint32_t size = memoryRegion.Size(); + uint64_t address = memoryRegion.StartAddress(); + total += size; + + while (size > 0) + { + uint32_t bytesToRead = std::min(size, (uint32_t)sizeof(m_tempBuffer)); + uint32_t read = 0; + + if (FAILED(m_crashInfo.DataTarget()->ReadVirtual(address, m_tempBuffer, bytesToRead, &read))) { + fprintf(stderr, "ReadVirtual(%016lx, %08x) FAILED\n", address, bytesToRead); + return false; + } + + if (!WriteData(m_tempBuffer, read)) { + return false; + } + + address += read; + size -= read; } - - address += read; - size -= read; } } diff --git a/src/debug/createdump/dumpwriter.h b/src/debug/createdump/dumpwriter.h index 0b4f88cbd6..7da0d63ccf 100644 --- a/src/debug/createdump/dumpwriter.h +++ b/src/debug/createdump/dumpwriter.h @@ -69,9 +69,3 @@ private: ); } }; - -static inline int sex() -{ - int probe = 1; - return !*(char *)&probe; -} diff --git a/src/debug/createdump/memoryregion.h b/src/debug/createdump/memoryregion.h index 1332ab1416..1f6c5f53e6 100644 --- a/src/debug/createdump/memoryregion.h +++ b/src/debug/createdump/memoryregion.h @@ -2,20 +2,31 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +enum MEMORY_REGION_FLAGS : uint32_t +{ + // PF_X = 0x01, // Execute + // PF_W = 0x02, // Write + // PF_R = 0x04, // Read + MEMORY_REGION_FLAG_PERMISSIONS_MASK = 0x0f, + MEMORY_REGION_FLAG_SHARED = 0x10, + MEMORY_REGION_FLAG_PRIVATE = 0x20, + MEMORY_REGION_FLAG_MEMORY_BACKED = 0x40 +}; + struct MemoryRegion { private: - uint32_t m_permissions; + uint32_t m_flags; uint64_t m_startAddress; uint64_t m_endAddress; uint64_t m_offset; // The name used for NT_FILE output - char* m_fileName; + const char* m_fileName; public: - MemoryRegion(uint64_t start, uint64_t end) : - m_permissions(PF_R | PF_W | PF_X), + MemoryRegion(uint32_t flags, uint64_t start, uint64_t end) : + m_flags(flags), m_startAddress(start), m_endAddress(end), m_offset(0), @@ -25,8 +36,8 @@ public: assert((end & ~PAGE_MASK) == 0); } - MemoryRegion(uint32_t permissions, uint64_t start, uint64_t end, uint64_t offset, char* filename) : - m_permissions(permissions), + MemoryRegion(uint32_t flags, uint64_t start, uint64_t end, uint64_t offset, const char* filename) : + m_flags(flags), m_startAddress(start), m_endAddress(end), m_offset(offset), @@ -36,7 +47,39 @@ public: assert((end & ~PAGE_MASK) == 0); } - const uint32_t Permissions() const { return m_permissions; } + // copy with new file name constructor + MemoryRegion(const MemoryRegion& region, const char* fileName) : + m_flags(region.m_flags), + m_startAddress(region.m_startAddress), + m_endAddress(region.m_endAddress), + m_offset(region.m_offset), + m_fileName(fileName) + { + } + + // copy with new flags constructor. The file name is not copied. + MemoryRegion(const MemoryRegion& region, uint32_t flags) : + m_flags(flags), + m_startAddress(region.m_startAddress), + m_endAddress(region.m_endAddress), + m_offset(region.m_offset), + m_fileName(nullptr) + { + } + + // copy constructor + MemoryRegion(const MemoryRegion& region) : + m_flags(region.m_flags), + m_startAddress(region.m_startAddress), + m_endAddress(region.m_endAddress), + m_offset(region.m_offset), + m_fileName(region.m_fileName) + { + } + + const uint32_t Permissions() const { return m_flags & MEMORY_REGION_FLAG_PERMISSIONS_MASK; } + const uint32_t Flags() const { return m_flags; } + const bool IsBackedByMemory() const { return (m_flags & MEMORY_REGION_FLAG_MEMORY_BACKED) != 0; } const uint64_t StartAddress() const { return m_startAddress; } const uint64_t EndAddress() const { return m_endAddress; } const uint64_t Size() const { return m_endAddress - m_startAddress; } @@ -48,27 +91,25 @@ public: return (m_startAddress < rhs.m_startAddress) && (m_endAddress <= rhs.m_startAddress); } + // Returns true if "rhs" is wholly contained in this one bool Contains(const MemoryRegion& rhs) const { return (m_startAddress <= rhs.m_startAddress) && (m_endAddress >= rhs.m_endAddress); } + // Free the file name memory void Cleanup() { if (m_fileName != nullptr) { - free(m_fileName); + free((void*)m_fileName); m_fileName = nullptr; } } - void Print() const + void Trace() const { - if (m_fileName != nullptr) { - TRACE("%016lx - %016lx (%06ld) %016lx %x %s\n", m_startAddress, m_endAddress, (Size() >> PAGE_SHIFT), m_offset, m_permissions, m_fileName); - } - else { - TRACE("%016lx - %016lx (%06ld) %x\n", m_startAddress, m_endAddress, (Size() >> PAGE_SHIFT), m_permissions); - } + TRACE("%s%016lx - %016lx (%06ld) %016lx %02x %s\n", IsBackedByMemory() ? "*" : " ", m_startAddress, m_endAddress, + (Size() >> PAGE_SHIFT), m_offset, m_flags, m_fileName != nullptr ? m_fileName : ""); } }; diff --git a/src/debug/createdump/threadinfo.cpp b/src/debug/createdump/threadinfo.cpp index e2c10fc4b7..35a4f0d4cd 100644 --- a/src/debug/createdump/threadinfo.cpp +++ b/src/debug/createdump/threadinfo.cpp @@ -145,21 +145,19 @@ ThreadInfo::GetThreadStack(const CrashInfo& crashInfo, uint64_t* startAddress, s *startAddress = m_gpRegisters.rsp & PAGE_MASK; *size = 4 * PAGE_SIZE; - for (const MemoryRegion& mapping : crashInfo.OtherMappings()) - { - if (*startAddress >= mapping.StartAddress() && *startAddress < mapping.EndAddress()) + const MemoryRegion* region = CrashInfo::SearchMemoryRegions(crashInfo.OtherMappings(), *startAddress); + if (region != nullptr) { + + // Use the mapping found for the size of the thread's stack + *size = region->EndAddress() - *startAddress; + + if (g_diagnostics) { - // Use the mapping found for the size of the thread's stack - *size = mapping.EndAddress() - *startAddress; - - if (g_diagnostics) - { - TRACE("Thread %04x stack found in other mapping (size %08lx): ", m_tid, *size); - mapping.Print(); - } - break; + TRACE("Thread %04x stack found in other mapping (size %08lx): ", m_tid, *size); + region->Trace(); } } + } void diff --git a/src/jit/lower.cpp b/src/jit/lower.cpp index 72dba4ee7e..9cab5eecf2 100644 --- a/src/jit/lower.cpp +++ b/src/jit/lower.cpp @@ -1723,14 +1723,14 @@ void Lowering::LowerFastTailCall(GenTreeCall* call) { tmpLclNum = comp->lvaGrabTemp( true DEBUGARG("Fast tail call lowering is creating a new local variable")); - comp->lvaSortAgain = true; - tmpType = genActualType(callerArgDsc->lvaArgType()); - comp->lvaTable[tmpLclNum].lvType = tmpType; - comp->lvaTable[tmpLclNum].lvRefCnt = 1; + comp->lvaSortAgain = true; + tmpType = genActualType(callerArgDsc->lvaArgType()); + comp->lvaTable[tmpLclNum].lvType = tmpType; + comp->lvaTable[tmpLclNum].lvRefCnt = 1; + comp->lvaTable[tmpLclNum].lvDoNotEnregister = comp->lvaTable[lcl->gtLclNum].lvDoNotEnregister; } lcl->SetLclNum(tmpLclNum); - lcl->SetOper(GT_LCL_VAR); } } } diff --git a/src/jit/morph.cpp b/src/jit/morph.cpp index 6928c3c393..9404469c7f 100644 --- a/src/jit/morph.cpp +++ b/src/jit/morph.cpp @@ -7529,6 +7529,39 @@ void Compiler::fgMorphRecursiveFastTailCallIntoLoop(BasicBlock* block, GenTreeCa fgInsertStmtBefore(block, paramAssignmentInsertionPoint, arg0AssignmentStmt); } + // If compInitMem is set, we may need to zero-initialize some locals. Normally it's done in the prolog + // but this loop can't include the prolog. Since we don't have liveness information, we insert zero-initialization + // for all non-parameter non-temp locals. Liveness phase will remove unnecessary initializations. + if (info.compInitMem) + { + unsigned varNum; + LclVarDsc* varDsc; + for (varNum = 0, varDsc = lvaTable; varNum < info.compLocalsCount; varNum++, varDsc++) + { + if (!varDsc->lvIsParam) + { + assert(!varDsc->lvIsTemp); + var_types lclType = varDsc->TypeGet(); + GenTreePtr lcl = gtNewLclvNode(varNum, lclType); + GenTreePtr init = nullptr; + if (lclType == TYP_STRUCT) + { + const bool isVolatile = false; + const bool isCopyBlock = false; + init = gtNewBlkOpNode(lcl, gtNewIconNode(0), varDsc->lvSize(), isVolatile, isCopyBlock); + init = fgMorphInitBlock(init); + } + else + { + GenTreePtr zero = gtNewZeroConNode(genActualType(lclType)); + init = gtNewAssignNode(lcl, zero); + } + GenTreePtr initStmt = gtNewStmt(init, callILOffset); + fgInsertStmtBefore(block, last, initStmt); + } + } + } + // Remove the call fgRemoveStmt(block, last); @@ -10514,6 +10547,43 @@ GenTree* Compiler::fgMorphForRegisterFP(GenTree* tree) return tree; } +//-------------------------------------------------------------------------------------------------------------- +// fgMorphRecognizeBoxNullable: +// Recognize this pattern: +// +// stmtExpr void (IL 0x000... ???) +// return int +// CNS_INT ref null +// EQ/NE/GT int +// CALL help ref HELPER.CORINFO_HELP_BOX_NULLABLE +// CNS_INT(h) long 0x7fed96836c8 class +// ADDR byref +// FIELD struct value +// LCL_VAR ref V00 this +// +// which comes from this code: +// +// return this.value==null; +// +// and transform it into +// +// stmtExpr void (IL 0x000... ???) +// return int +// CNS_INT ref null +// EQ/NE/GT int +// IND bool +// ADDR byref +// FIELD struct value +// LCL_VAR ref V00 this +// +// Arguments: +// compare - Compare tree to optimize. +// +// return value: +// A tree that has a call to CORINFO_HELP_BOX_NULLABLE optimized away if the pattern is found; +// the original tree otherwise. +// + GenTree* Compiler::fgMorphRecognizeBoxNullable(GenTree* compare) { GenTree* op1 = compare->gtOp.gtOp1; @@ -10521,26 +10591,6 @@ GenTree* Compiler::fgMorphRecognizeBoxNullable(GenTree* compare) GenTree* opCns; GenTreeCall* opCall; - // recognize this pattern: - // - // stmtExpr void (IL 0x000... ???) - // return int - // const ref null - // == int - // call help ref HELPER.CORINFO_HELP_BOX_NULLABLE - // const(h) long 0x7fed96836c8 class - // addr byref - // ld.lclVar struct V00 arg0 - // - // - // which comes from this code (reported by customer as being slow) : - // - // private static bool IsNull(T arg) - // { - // return arg==null; - // } - // - if (op1->IsCnsIntOrI() && op2->IsHelperCall()) { opCns = op1; @@ -10566,8 +10616,17 @@ GenTree* Compiler::fgMorphRecognizeBoxNullable(GenTree* compare) return compare; } - // replace the box with an access of the nullable 'hasValue' field which is at the zero offset - GenTree* newOp = gtNewOperNode(GT_IND, TYP_BOOL, opCall->gtCall.gtCallArgs->gtOp.gtOp2->gtOp.gtOp1); + // Get the nullable struct argument + GenTree* arg = opCall->gtCall.gtCallArgs->gtOp.gtOp2->gtOp.gtOp1; + + // Check for cases that are unsafe to optimize and return the unchanged tree + if (arg->IsArgPlaceHolderNode() || arg->IsNothingNode() || ((arg->gtFlags & GTF_LATE_ARG) != 0)) + { + return compare; + } + + // Replace the box with an access of the nullable 'hasValue' field which is at the zero offset + GenTree* newOp = gtNewOperNode(GT_IND, TYP_BOOL, arg); if (opCall == op1) { @@ -11426,7 +11485,17 @@ GenTreePtr Compiler::fgMorphSmpOp(GenTreePtr tree, MorphAddrContext* mac) } } } - fgMorphRecognizeBoxNullable(tree); + + __fallthrough; + + case GT_GT: + + // Try to optimize away calls to CORINFO_HELP_BOX_NULLABLE for GT_EQ, GT_NE, and unsigned GT_GT. + if ((oper != GT_GT) || tree->IsUnsigned()) + { + fgMorphRecognizeBoxNullable(tree); + } + op1 = tree->gtOp.gtOp1; op2 = tree->gtGetOp2IfPresent(); diff --git a/src/mscorlib/System.Private.CoreLib.csproj b/src/mscorlib/System.Private.CoreLib.csproj index 513e002497..18256086d7 100644 --- a/src/mscorlib/System.Private.CoreLib.csproj +++ b/src/mscorlib/System.Private.CoreLib.csproj @@ -619,7 +619,6 @@ - diff --git a/src/mscorlib/shared/System/Char.cs b/src/mscorlib/shared/System/Char.cs index 3fad7a4827..72441763e9 100644 --- a/src/mscorlib/shared/System/Char.cs +++ b/src/mscorlib/shared/System/Char.cs @@ -21,6 +21,7 @@ namespace System { [Serializable] [StructLayout(LayoutKind.Sequential)] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public struct Char : IComparable, IComparable, IEquatable, IConvertible { // diff --git a/src/mscorlib/shared/System/Collections/DictionaryEntry.cs b/src/mscorlib/shared/System/Collections/DictionaryEntry.cs index 290306d006..3c1c0befa3 100644 --- a/src/mscorlib/shared/System/Collections/DictionaryEntry.cs +++ b/src/mscorlib/shared/System/Collections/DictionaryEntry.cs @@ -9,10 +9,11 @@ namespace System.Collections // A DictionaryEntry holds a key and a value from a dictionary. // It is returned by IDictionaryEnumerator::GetEntry(). [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public struct DictionaryEntry { - private Object _key; - private Object _value; + private Object _key; // Do not rename (binary serialization) + private Object _value; // Do not rename (binary serialization) // Constructs a new DictionaryEnumerator by setting the Key // and Value fields appropriately. diff --git a/src/mscorlib/shared/System/Collections/Generic/KeyValuePair.cs b/src/mscorlib/shared/System/Collections/Generic/KeyValuePair.cs index fc51af25f8..aeafecd958 100644 --- a/src/mscorlib/shared/System/Collections/Generic/KeyValuePair.cs +++ b/src/mscorlib/shared/System/Collections/Generic/KeyValuePair.cs @@ -46,10 +46,11 @@ namespace System.Collections.Generic // It is used by the IEnumerable implementation for both IDictionary // and IReadOnlyDictionary. [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public struct KeyValuePair { - private TKey key; // DO NOT change the field name, it's required for compatibility with desktop .NET as it appears in serialization payload. - private TValue value; // DO NOT change the field name, it's required for compatibility with desktop .NET as it appears in serialization payload. + private TKey key; // Do not rename (binary serialization) + private TValue value; // Do not rename (binary serialization) public KeyValuePair(TKey key, TValue value) { diff --git a/src/mscorlib/shared/System/DateTime.cs b/src/mscorlib/shared/System/DateTime.cs index ddb72da77d..4fd9727fcd 100644 --- a/src/mscorlib/shared/System/DateTime.cs +++ b/src/mscorlib/shared/System/DateTime.cs @@ -54,6 +54,7 @@ namespace System // [StructLayout(LayoutKind.Auto)] [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public partial struct DateTime : IComparable, IFormattable, IConvertible, IComparable, IEquatable, ISerializable { // Number of 100ns ticks per time unit @@ -125,8 +126,8 @@ namespace System private const UInt64 KindLocalAmbiguousDst = 0xC000000000000000; private const Int32 KindShift = 62; - private const String TicksField = "ticks"; - private const String DateDataField = "_dateData"; + private const String TicksField = "ticks"; // Do not rename (binary serialization) + private const String DateDataField = "dateData"; // Do not rename (binary serialization) // The data is stored as an unsigned 64-bit integeter // Bits 01-62: The value of 100-nanosecond ticks where 0 represents 1/1/0001 12:00am, up until the value diff --git a/src/mscorlib/shared/System/DateTimeOffset.cs b/src/mscorlib/shared/System/DateTimeOffset.cs index d5ccbd9195..ab35bdb0fe 100644 --- a/src/mscorlib/shared/System/DateTimeOffset.cs +++ b/src/mscorlib/shared/System/DateTimeOffset.cs @@ -30,6 +30,7 @@ namespace System [StructLayout(LayoutKind.Auto)] [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public struct DateTimeOffset : IComparable, IFormattable, IComparable, IEquatable, ISerializable, IDeserializationCallback { // Constants @@ -573,8 +574,8 @@ namespace System throw new ArgumentNullException(nameof(info)); } - info.AddValue("DateTime", _dateTime); - info.AddValue("OffsetMinutes", _offsetMinutes); + info.AddValue("DateTime", _dateTime); // Do not rename (binary serialization) + info.AddValue("OffsetMinutes", _offsetMinutes); // Do not rename (binary serialization) } @@ -585,8 +586,8 @@ namespace System throw new ArgumentNullException(nameof(info)); } - _dateTime = (DateTime)info.GetValue("DateTime", typeof(DateTime)); - _offsetMinutes = (Int16)info.GetValue("OffsetMinutes", typeof(Int16)); + _dateTime = (DateTime)info.GetValue("DateTime", typeof(DateTime)); // Do not rename (binary serialization) + _offsetMinutes = (Int16)info.GetValue("OffsetMinutes", typeof(Int16)); // Do not rename (binary serialization) } // Returns the hash code for this DateTimeOffset. diff --git a/src/mscorlib/shared/System/Globalization/SortVersion.cs b/src/mscorlib/shared/System/Globalization/SortVersion.cs index 94c04d7063..46e9a833ec 100644 --- a/src/mscorlib/shared/System/Globalization/SortVersion.cs +++ b/src/mscorlib/shared/System/Globalization/SortVersion.cs @@ -5,6 +5,7 @@ namespace System.Globalization { [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public sealed class SortVersion : IEquatable { private int m_NlsVersion; // Do not rename (binary serialization) diff --git a/src/mscorlib/shared/System/Reflection/Assembly.cs b/src/mscorlib/shared/System/Reflection/Assembly.cs index b965c9f7fb..d35ffc7066 100644 --- a/src/mscorlib/shared/System/Reflection/Assembly.cs +++ b/src/mscorlib/shared/System/Reflection/Assembly.cs @@ -125,10 +125,7 @@ namespace System.Reflection public virtual FileStream[] GetFiles() => GetFiles(getResourceModules: false); public virtual FileStream[] GetFiles(bool getResourceModules) { throw NotImplemented.ByDesign; } - public virtual void GetObjectData(SerializationInfo info, StreamingContext context) - { - throw new PlatformNotSupportedException(); - } + public virtual void GetObjectData(SerializationInfo info, StreamingContext context) { throw NotImplemented.ByDesign; } public override string ToString() { diff --git a/src/mscorlib/shared/System/Reflection/Module.cs b/src/mscorlib/shared/System/Reflection/Module.cs index 7822e9ff10..56f83c40d9 100644 --- a/src/mscorlib/shared/System/Reflection/Module.cs +++ b/src/mscorlib/shared/System/Reflection/Module.cs @@ -110,10 +110,7 @@ namespace System.Reflection public Type ResolveType(int metadataToken) => ResolveType(metadataToken, null, null); public virtual Type ResolveType(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments) { throw NotImplemented.ByDesign; } - public virtual void GetObjectData(SerializationInfo info, StreamingContext context) - { - throw new PlatformNotSupportedException(); - } + public virtual void GetObjectData(SerializationInfo info, StreamingContext context) { throw NotImplemented.ByDesign; } public override bool Equals(object o) => base.Equals(o); public override int GetHashCode() => base.GetHashCode(); diff --git a/src/mscorlib/shared/System/Reflection/ParameterInfo.cs b/src/mscorlib/shared/System/Reflection/ParameterInfo.cs index fd130e569b..94bfffaa53 100644 --- a/src/mscorlib/shared/System/Reflection/ParameterInfo.cs +++ b/src/mscorlib/shared/System/Reflection/ParameterInfo.cs @@ -54,7 +54,46 @@ namespace System.Reflection public object GetRealObject(StreamingContext context) { - throw new PlatformNotSupportedException(); + // Once all the serializable fields have come in we can set up the real + // instance based on just two of them (MemberImpl and PositionImpl). + + if (MemberImpl == null) + throw new SerializationException(SR.Serialization_InsufficientState); + + ParameterInfo[] args = null; + + switch (MemberImpl.MemberType) + { + case MemberTypes.Constructor: + case MemberTypes.Method: + if (PositionImpl == -1) + { + if (MemberImpl.MemberType == MemberTypes.Method) + return ((MethodInfo)MemberImpl).ReturnParameter; + else + throw new SerializationException(SR.Serialization_BadParameterInfo); + } + else + { + args = ((MethodBase)MemberImpl).GetParametersNoCopy(); + + if (args != null && PositionImpl < args.Length) + return args[PositionImpl]; + else + throw new SerializationException(SR.Serialization_BadParameterInfo); + } + + case MemberTypes.Property: + args = ((PropertyInfo)MemberImpl).GetIndexParameters(); + + if (args != null && PositionImpl > -1 && PositionImpl < args.Length) + return args[PositionImpl]; + else + throw new SerializationException(SR.Serialization_BadParameterInfo); + + default: + throw new SerializationException(SR.Serialization_NoParameterInfo); + } } public override string ToString() => ParameterType.FormatTypeName() + " " + Name; diff --git a/src/mscorlib/shared/System/StringComparer.cs b/src/mscorlib/shared/System/StringComparer.cs index b327e770d5..6990378812 100644 --- a/src/mscorlib/shared/System/StringComparer.cs +++ b/src/mscorlib/shared/System/StringComparer.cs @@ -6,15 +6,17 @@ using System.Collections; using System.Collections.Generic; using System.Globalization; using System.Diagnostics.Contracts; +using System.Runtime.Serialization; namespace System { [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public abstract class StringComparer : IComparer, IEqualityComparer, IComparer, IEqualityComparer { private static readonly CultureAwareComparer s_invariantCulture = new CultureAwareComparer(CultureInfo.InvariantCulture, false); private static readonly CultureAwareComparer s_invariantCultureIgnoreCase = new CultureAwareComparer(CultureInfo.InvariantCulture, true); - private static readonly OrdinalComparer s_ordinal = new OrdinalComparer(); + private static readonly OrdinalCaseSensitiveComparer s_ordinal = new OrdinalCaseSensitiveComparer(); private static readonly OrdinalIgnoreCaseComparer s_ordinalIgnoreCase = new OrdinalIgnoreCaseComparer(); public static StringComparer InvariantCulture @@ -170,30 +172,33 @@ namespace System } [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] internal sealed class CultureAwareComparer : StringComparer { - private readonly CompareInfo _compareInfo; - private readonly CompareOptions _options; + private readonly CompareInfo _compareInfo; // Do not rename (binary serialization) + private readonly bool _ignoreCase; // Do not rename (binary serialization) internal CultureAwareComparer(CultureInfo culture, bool ignoreCase) { _compareInfo = culture.CompareInfo; - _options = ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None; + _ignoreCase = ignoreCase; } + private CompareOptions Options => _ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None; + public override int Compare(string x, string y) { if (object.ReferenceEquals(x, y)) return 0; if (x == null) return -1; if (y == null) return 1; - return _compareInfo.Compare(x, y, _options); + return _compareInfo.Compare(x, y, Options); } public override bool Equals(string x, string y) { if (object.ReferenceEquals(x, y)) return true; if (x == null || y == null) return false; - return _compareInfo.Compare(x, y, _options) == 0; + return _compareInfo.Compare(x, y, Options) == 0; } public override int GetHashCode(string obj) @@ -202,7 +207,7 @@ namespace System { throw new ArgumentNullException(nameof(obj)); } - return _compareInfo.GetHashCodeOfString(obj, _options); + return _compareInfo.GetHashCodeOfString(obj, Options); } // Equals method for the comparer itself. @@ -211,20 +216,108 @@ namespace System CultureAwareComparer comparer = obj as CultureAwareComparer; return comparer != null && - _options == comparer._options && + _ignoreCase == comparer._ignoreCase && _compareInfo.Equals(comparer._compareInfo); } public override int GetHashCode() { int hashCode = _compareInfo.GetHashCode(); - return _options == CompareOptions.None ? hashCode : ~hashCode; + return _ignoreCase ? ~hashCode : hashCode; + } + } + + [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] + internal class OrdinalComparer : StringComparer + { + private readonly bool _ignoreCase; // Do not rename (binary serialization) + + internal OrdinalComparer(bool ignoreCase) + { + _ignoreCase = ignoreCase; + } + + public override int Compare(string x, string y) + { + if (ReferenceEquals(x, y)) + return 0; + if (x == null) + return -1; + if (y == null) + return 1; + + if (_ignoreCase) + { + return string.Compare(x, y, StringComparison.OrdinalIgnoreCase); + } + + return string.CompareOrdinal(x, y); + } + + public override bool Equals(string x, string y) + { + if (ReferenceEquals(x, y)) + return true; + if (x == null || y == null) + return false; + + if (_ignoreCase) + { + if (x.Length != y.Length) + { + return false; + } + return (string.Compare(x, y, StringComparison.OrdinalIgnoreCase) == 0); + } + return x.Equals(y); + } + + public override int GetHashCode(string obj) + { + if (obj == null) + { +#if CORECLR + ThrowHelper.ThrowArgumentNullException(ExceptionArgument.obj); +#else + throw new ArgumentNullException(nameof(obj)); +#endif + } + Contract.EndContractBlock(); + + if (_ignoreCase) + { + return TextInfo.GetHashCodeOrdinalIgnoreCase(obj); + } + + return obj.GetHashCode(); + } + + // Equals method for the comparer itself. + public override bool Equals(object obj) + { + OrdinalComparer comparer = obj as OrdinalComparer; + if (comparer == null) + { + return false; + } + return (this._ignoreCase == comparer._ignoreCase); + } + + public override int GetHashCode() + { + int hashCode = nameof(OrdinalComparer).GetHashCode(); + return _ignoreCase ? (~hashCode) : hashCode; } } [Serializable] - internal sealed class OrdinalComparer : StringComparer + internal sealed class OrdinalCaseSensitiveComparer : OrdinalComparer, ISerializable { + public OrdinalCaseSensitiveComparer() : base(false) + { + } + public override int Compare(string x, string y) => string.CompareOrdinal(x, y); public override bool Equals(string x, string y) => string.Equals(x, y); @@ -242,14 +335,20 @@ namespace System return obj.GetHashCode(); } - // Equals/GetHashCode methods for the comparer itself. - public override bool Equals(object obj) => obj is OrdinalComparer; - public override int GetHashCode() => nameof(OrdinalComparer).GetHashCode(); + public void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.SetType(typeof(OrdinalComparer)); + info.AddValue("_ignoreCase", false); + } } - [Serializable] - internal sealed class OrdinalIgnoreCaseComparer : StringComparer + [Serializable] + internal sealed class OrdinalIgnoreCaseComparer : OrdinalComparer, ISerializable { + public OrdinalIgnoreCaseComparer() : base(true) + { + } + public override int Compare(string x, string y) => string.Compare(x, y, StringComparison.OrdinalIgnoreCase); public override bool Equals(string x, string y) => string.Equals(x, y, StringComparison.OrdinalIgnoreCase); @@ -267,8 +366,10 @@ namespace System return TextInfo.GetHashCodeOrdinalIgnoreCase(obj); } - // Equals/GetHashCode methods for the comparer itself. - public override bool Equals(object obj) => obj is OrdinalIgnoreCaseComparer; - public override int GetHashCode() => nameof(OrdinalIgnoreCaseComparer).GetHashCode(); + public void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.SetType(typeof(OrdinalComparer)); + info.AddValue("_ignoreCase", true); + } } } diff --git a/src/mscorlib/shared/System/Text/StringBuilder.cs b/src/mscorlib/shared/System/Text/StringBuilder.cs index 3a06114bff..1167016cc1 100644 --- a/src/mscorlib/shared/System/Text/StringBuilder.cs +++ b/src/mscorlib/shared/System/Text/StringBuilder.cs @@ -35,6 +35,7 @@ namespace System.Text // Console.WriteLine(sb2); // [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public sealed partial class StringBuilder : ISerializable { // A StringBuilder is internally represented as a linked list of blocks each of which holds @@ -58,10 +59,11 @@ namespace System.Text // // internal const int DefaultCapacity = 16; - private const String CapacityField = "Capacity"; - private const String MaxCapacityField = "m_MaxCapacity"; - private const String StringValueField = "m_StringValue"; - private const String ThreadIDField = "m_currentThread"; + private const String CapacityField = "Capacity"; // Do not rename (binary serialization) + private const String MaxCapacityField = "m_MaxCapacity"; // Do not rename (binary serialization) + private const String StringValueField = "m_StringValue"; // Do not rename (binary serialization) + private const String ThreadIDField = "m_currentThread"; // Do not rename (binary serialization) + // We want to keep chunk arrays out of large object heap (< 85K bytes ~ 40K chars) to be sure. // Making the maximum chunk size big means less allocation code called, but also more waste // in unused characters and slower inserts / replaces (since you do need to slide characters over diff --git a/src/mscorlib/shared/System/ValueTuple.cs b/src/mscorlib/shared/System/ValueTuple.cs index e0cd02e914..3464f2781c 100644 --- a/src/mscorlib/shared/System/ValueTuple.cs +++ b/src/mscorlib/shared/System/ValueTuple.cs @@ -29,6 +29,7 @@ namespace System /// - their members (such as Item1, Item2, etc) are fields rather than properties. /// [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public struct ValueTuple : IEquatable, IStructuralEquatable, IStructuralComparable, IComparable, IComparable, IValueTupleInternal, ITuple { @@ -298,6 +299,7 @@ namespace System /// Represents a 1-tuple, or singleton, as a value type. /// The type of the tuple's only component. [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public struct ValueTuple : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple { @@ -464,6 +466,7 @@ namespace System /// The type of the tuple's second component. [Serializable] [StructLayout(LayoutKind.Auto)] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public struct ValueTuple : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple { @@ -674,6 +677,7 @@ namespace System /// The type of the tuple's third component. [Serializable] [StructLayout(LayoutKind.Auto)] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public struct ValueTuple : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple { @@ -882,6 +886,7 @@ namespace System /// The type of the tuple's fourth component. [Serializable] [StructLayout(LayoutKind.Auto)] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public struct ValueTuple : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple { @@ -1109,6 +1114,7 @@ namespace System /// The type of the tuple's fifth component. [Serializable] [StructLayout(LayoutKind.Auto)] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public struct ValueTuple : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple { @@ -1355,6 +1361,7 @@ namespace System /// The type of the tuple's sixth component. [Serializable] [StructLayout(LayoutKind.Auto)] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public struct ValueTuple : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple { @@ -1620,6 +1627,7 @@ namespace System /// The type of the tuple's seventh component. [Serializable] [StructLayout(LayoutKind.Auto)] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public struct ValueTuple : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple { @@ -1904,6 +1912,7 @@ namespace System /// The type of the tuple's eighth component. [Serializable] [StructLayout(LayoutKind.Auto)] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public struct ValueTuple : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple where TRest : struct diff --git a/src/mscorlib/shared/System/Version.cs b/src/mscorlib/shared/System/Version.cs index 54b2052ddb..a2140ab137 100644 --- a/src/mscorlib/shared/System/Version.cs +++ b/src/mscorlib/shared/System/Version.cs @@ -16,14 +16,15 @@ namespace System // specified component. [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public sealed class Version : ICloneable, IComparable , IComparable, IEquatable { // AssemblyName depends on the order staying the same - private readonly int _Major; - private readonly int _Minor; - private readonly int _Build = -1; - private readonly int _Revision = -1; + private readonly int _Major; // Do not rename (binary serialization) + private readonly int _Minor; // Do not rename (binary serialization) + private readonly int _Build = -1; // Do not rename (binary serialization) + private readonly int _Revision = -1; // Do not rename (binary serialization) public Version(int major, int minor, int build, int revision) { diff --git a/src/mscorlib/src/System/AggregateException.cs b/src/mscorlib/src/System/AggregateException.cs index 22bc323215..0b840972ef 100644 --- a/src/mscorlib/src/System/AggregateException.cs +++ b/src/mscorlib/src/System/AggregateException.cs @@ -30,9 +30,10 @@ namespace System /// [Serializable] [DebuggerDisplay("Count = {InnerExceptionCount}")] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public class AggregateException : Exception { - private ReadOnlyCollection m_innerExceptions; // Complete set of exceptions. + private ReadOnlyCollection m_innerExceptions; // Complete set of exceptions. Do not rename (binary serialization) /// /// Initializes a new instance of the class. diff --git a/src/mscorlib/src/System/Array.cs b/src/mscorlib/src/System/Array.cs index fcfeb94675..62a4ecf16e 100644 --- a/src/mscorlib/src/System/Array.cs +++ b/src/mscorlib/src/System/Array.cs @@ -26,6 +26,7 @@ namespace System // Note that we make a T[] (single-dimensional w/ zero as the lower bound) implement both // IList and IReadOnlyList, where T : U dynamically. See the SZArrayHelper class for details. [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public abstract class Array : ICloneable, IList, IStructuralComparable, IStructuralEquatable { // This ctor exists solely to prevent C# from generating a protected .ctor that violates the surface area. I really want this to be a diff --git a/src/mscorlib/src/System/ArraySegment.cs b/src/mscorlib/src/System/ArraySegment.cs index 664352708d..7546c5bd56 100644 --- a/src/mscorlib/src/System/ArraySegment.cs +++ b/src/mscorlib/src/System/ArraySegment.cs @@ -26,15 +26,16 @@ namespace System // three fields from an ArraySegment may not see the same ArraySegment from one call to another // (ie, users could assign a new value to the old location). [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public struct ArraySegment : IList, IReadOnlyList { // Do not replace the array allocation with Array.Empty. We don't want to have the overhead of // instantiating another generic type in addition to ArraySegment for new type parameters. public static ArraySegment Empty { get; } = new ArraySegment(new T[0]); - private readonly T[] _array; - private readonly int _offset; - private readonly int _count; + private readonly T[] _array; // Do not rename (binary serialization) + private readonly int _offset; // Do not rename (binary serialization) + private readonly int _count; // Do not rename (binary serialization) public ArraySegment(T[] array) { diff --git a/src/mscorlib/src/System/Attribute.cs b/src/mscorlib/src/System/Attribute.cs index baa9a71638..23fd9aaaaf 100644 --- a/src/mscorlib/src/System/Attribute.cs +++ b/src/mscorlib/src/System/Attribute.cs @@ -17,6 +17,7 @@ namespace System { [Serializable] [AttributeUsageAttribute(AttributeTargets.All, Inherited = true, AllowMultiple = false)] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public abstract class Attribute { #region Private Statics diff --git a/src/mscorlib/src/System/Boolean.cs b/src/mscorlib/src/System/Boolean.cs index 59cab74456..a1f5064964 100644 --- a/src/mscorlib/src/System/Boolean.cs +++ b/src/mscorlib/src/System/Boolean.cs @@ -21,6 +21,7 @@ namespace System // The Boolean class provides the // object representation of the boolean primitive type. [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public struct Boolean : IComparable, IConvertible, IComparable, IEquatable { // diff --git a/src/mscorlib/src/System/Byte.cs b/src/mscorlib/src/System/Byte.cs index da3b790ac6..fafdcbb535 100644 --- a/src/mscorlib/src/System/Byte.cs +++ b/src/mscorlib/src/System/Byte.cs @@ -25,6 +25,7 @@ namespace System // [Serializable] [System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public struct Byte : IComparable, IFormattable, IConvertible , IComparable, IEquatable { diff --git a/src/mscorlib/src/System/Collections/Comparer.cs b/src/mscorlib/src/System/Collections/Comparer.cs index 76e19e77f1..00259e6bdb 100644 --- a/src/mscorlib/src/System/Collections/Comparer.cs +++ b/src/mscorlib/src/System/Collections/Comparer.cs @@ -13,21 +13,17 @@ ** ===========================================================*/ -using System; using System.Globalization; -using System.Runtime.Serialization; using System.Diagnostics.Contracts; namespace System.Collections { - internal sealed class Comparer : IComparer, ISerializable + internal sealed class Comparer : IComparer { private CompareInfo m_compareInfo; public static readonly Comparer Default = new Comparer(CultureInfo.CurrentCulture); public static readonly Comparer DefaultInvariant = new Comparer(CultureInfo.InvariantCulture); - private const String CompareInfoName = "CompareInfo"; - private Comparer() { m_compareInfo = null; @@ -73,10 +69,5 @@ namespace System.Collections throw new ArgumentException(SR.Argument_ImplementIComparable); } - - public void GetObjectData(SerializationInfo info, StreamingContext context) - { - throw new PlatformNotSupportedException(); - } } } diff --git a/src/mscorlib/src/System/Collections/Generic/Comparer.cs b/src/mscorlib/src/System/Collections/Generic/Comparer.cs index e163faa80f..47c241500d 100644 --- a/src/mscorlib/src/System/Collections/Generic/Comparer.cs +++ b/src/mscorlib/src/System/Collections/Generic/Comparer.cs @@ -18,6 +18,7 @@ namespace System.Collections.Generic { [Serializable] [TypeDependencyAttribute("System.Collections.Generic.ObjectComparer`1")] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public abstract class Comparer : IComparer, IComparer { // To minimize generic instantiation overhead of creating the comparer per type, we keep the generic portion of the code as small @@ -52,6 +53,7 @@ namespace System.Collections.Generic // means another generic instantiation, which can be costly esp. // for value types. [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] internal sealed class GenericComparer : Comparer where T : IComparable { public override int Compare(T x, T y) @@ -74,6 +76,7 @@ namespace System.Collections.Generic } [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] internal sealed class NullableComparer : Comparer where T : struct, IComparable { public override int Compare(T? x, T? y) @@ -96,6 +99,7 @@ namespace System.Collections.Generic } [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] internal sealed class ObjectComparer : Comparer { public override int Compare(T x, T y) @@ -132,6 +136,7 @@ namespace System.Collections.Generic // since we want to serialize as ObjectComparer for // back-compat reasons (see below). [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] internal sealed class Int32EnumComparer : Comparer, ISerializable where T : struct { public Int32EnumComparer() @@ -167,6 +172,7 @@ namespace System.Collections.Generic } [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] internal sealed class UInt32EnumComparer : Comparer, ISerializable where T : struct { public UInt32EnumComparer() @@ -198,6 +204,7 @@ namespace System.Collections.Generic } [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] internal sealed class Int64EnumComparer : Comparer, ISerializable where T : struct { public Int64EnumComparer() @@ -226,6 +233,7 @@ namespace System.Collections.Generic } [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] internal sealed class UInt64EnumComparer : Comparer, ISerializable where T : struct { public UInt64EnumComparer() diff --git a/src/mscorlib/src/System/Collections/Generic/Dictionary.cs b/src/mscorlib/src/System/Collections/Generic/Dictionary.cs index cd33428ca1..50724017dd 100644 --- a/src/mscorlib/src/System/Collections/Generic/Dictionary.cs +++ b/src/mscorlib/src/System/Collections/Generic/Dictionary.cs @@ -52,6 +52,7 @@ namespace System.Collections.Generic [DebuggerTypeProxy(typeof(Mscorlib_DictionaryDebugView<,>))] [DebuggerDisplay("Count = {Count}")] [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public class Dictionary : IDictionary, IDictionary, IReadOnlyDictionary, ISerializable, IDeserializationCallback { private struct Entry @@ -74,10 +75,10 @@ namespace System.Collections.Generic private Object _syncRoot; // constants for serialization - private const String VersionName = "Version"; - private const String HashSizeName = "HashSize"; // Must save buckets.Length - private const String KeyValuePairsName = "KeyValuePairs"; - private const String ComparerName = "Comparer"; + private const String VersionName = "Version"; // Do not rename (binary serialization) + private const String HashSizeName = "HashSize"; // Do not rename (binary serialization). Must save buckets.Length + private const String KeyValuePairsName = "KeyValuePairs"; // Do not rename (binary serialization) + private const String ComparerName = "Comparer"; // Do not rename (binary serialization) public Dictionary() : this(0, null) { } diff --git a/src/mscorlib/src/System/Collections/Generic/EqualityComparer.cs b/src/mscorlib/src/System/Collections/Generic/EqualityComparer.cs index d6b213c9d7..760c9d10b2 100644 --- a/src/mscorlib/src/System/Collections/Generic/EqualityComparer.cs +++ b/src/mscorlib/src/System/Collections/Generic/EqualityComparer.cs @@ -17,6 +17,7 @@ namespace System.Collections.Generic { [Serializable] [TypeDependencyAttribute("System.Collections.Generic.ObjectEqualityComparer`1")] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public abstract class EqualityComparer : IEqualityComparer, IEqualityComparer { // To minimize generic instantiation overhead of creating the comparer per type, we keep the generic portion of the code as small @@ -69,6 +70,7 @@ namespace System.Collections.Generic // The methods in this class look identical to the inherited methods, but the calls // to Equal bind to IEquatable.Equals(T) instead of Object.Equals(Object) [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] internal class GenericEqualityComparer : EqualityComparer where T : IEquatable { [Pure] @@ -137,6 +139,7 @@ namespace System.Collections.Generic } [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] internal sealed class NullableEqualityComparer : EqualityComparer where T : struct, IEquatable { [Pure] @@ -203,6 +206,7 @@ namespace System.Collections.Generic } [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] internal sealed class ObjectEqualityComparer : EqualityComparer { [Pure] @@ -275,6 +279,7 @@ namespace System.Collections.Generic // keep the perofrmance not affected till we hit collision threshold and then we switch to the comparer which is using // randomized string hashing GenericEqualityComparer [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] internal class NonRandomizedStringEqualityComparer : GenericEqualityComparer { private static IEqualityComparer s_nonRandomizedComparer; @@ -302,6 +307,7 @@ namespace System.Collections.Generic // Performance of IndexOf on byte array is very important for some scenarios. // We will call the C runtime function memchr, which is optimized. [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] internal sealed class ByteEqualityComparer : EqualityComparer { [Pure] @@ -353,6 +359,7 @@ namespace System.Collections.Generic } [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] internal class EnumEqualityComparer : EqualityComparer, ISerializable where T : struct { [Pure] @@ -416,6 +423,7 @@ namespace System.Collections.Generic } [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] internal sealed class SByteEnumEqualityComparer : EnumEqualityComparer where T : struct { public SByteEnumEqualityComparer() { } @@ -432,6 +440,7 @@ namespace System.Collections.Generic } [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] internal sealed class ShortEnumEqualityComparer : EnumEqualityComparer, ISerializable where T : struct { public ShortEnumEqualityComparer() { } @@ -448,6 +457,7 @@ namespace System.Collections.Generic } [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] internal sealed class LongEnumEqualityComparer : EqualityComparer, ISerializable where T : struct { [Pure] diff --git a/src/mscorlib/src/System/Collections/Generic/List.cs b/src/mscorlib/src/System/Collections/Generic/List.cs index 94e794cfd2..2031ddc6ed 100644 --- a/src/mscorlib/src/System/Collections/Generic/List.cs +++ b/src/mscorlib/src/System/Collections/Generic/List.cs @@ -30,14 +30,15 @@ namespace System.Collections.Generic [DebuggerTypeProxy(typeof(Mscorlib_CollectionDebugView<>))] [DebuggerDisplay("Count = {Count}")] [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public class List : IList, System.Collections.IList, IReadOnlyList { private const int _defaultCapacity = 4; - private T[] _items; + private T[] _items; // Do not rename (binary serialization) [ContractPublicPropertyName("Count")] - private int _size; - private int _version; + private int _size; // Do not rename (binary serialization) + private int _version; // Do not rename (binary serialization) [NonSerialized] private Object _syncRoot; diff --git a/src/mscorlib/src/System/Collections/ListDictionaryInternal.cs b/src/mscorlib/src/System/Collections/ListDictionaryInternal.cs index 3f92038d4f..17eb89a2b2 100644 --- a/src/mscorlib/src/System/Collections/ListDictionaryInternal.cs +++ b/src/mscorlib/src/System/Collections/ListDictionaryInternal.cs @@ -20,11 +20,12 @@ namespace System.Collections /// will be smaller and faster than a Hashtable if the number of elements is 10 or less. /// This should not be used if performance is important for large numbers of elements. [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] internal class ListDictionaryInternal : IDictionary { - private DictionaryNode head; - private int version; - private int count; + private DictionaryNode head; // Do not rename (binary serialization) + private int version; // Do not rename (binary serialization) + private int count; // Do not rename (binary serialization) [NonSerialized] private Object _syncRoot; diff --git a/src/mscorlib/src/System/Collections/ObjectModel/Collection.cs b/src/mscorlib/src/System/Collections/ObjectModel/Collection.cs index d9801dfaaf..8e5de70e72 100644 --- a/src/mscorlib/src/System/Collections/ObjectModel/Collection.cs +++ b/src/mscorlib/src/System/Collections/ObjectModel/Collection.cs @@ -15,9 +15,10 @@ namespace System.Collections.ObjectModel [Serializable] [DebuggerTypeProxy(typeof(Mscorlib_CollectionDebugView<>))] [DebuggerDisplay("Count = {Count}")] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public class Collection : IList, IList, IReadOnlyList { - private IList items; + private IList items; // Do not rename (binary serialization) [NonSerialized] private Object _syncRoot; diff --git a/src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyCollection.cs b/src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyCollection.cs index b484879c27..03c7d45e16 100644 --- a/src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyCollection.cs +++ b/src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyCollection.cs @@ -15,9 +15,10 @@ namespace System.Collections.ObjectModel [Serializable] [DebuggerTypeProxy(typeof(Mscorlib_CollectionDebugView<>))] [DebuggerDisplay("Count = {Count}")] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public class ReadOnlyCollection : IList, IList, IReadOnlyList { - private IList list; + private IList list; // Do not rename (binary serialization) [NonSerialized] private Object _syncRoot; diff --git a/src/mscorlib/src/System/Decimal.cs b/src/mscorlib/src/System/Decimal.cs index ce59a99334..b120a368da 100644 --- a/src/mscorlib/src/System/Decimal.cs +++ b/src/mscorlib/src/System/Decimal.cs @@ -59,6 +59,7 @@ namespace System [StructLayout(LayoutKind.Sequential)] [Serializable] [System.Runtime.Versioning.NonVersionable] // This only applies to field layout + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public struct Decimal : IFormattable, IComparable, IConvertible, IComparable, IEquatable, IDeserializationCallback { // Sign mask for the flags field. A value of zero in this bit indicates a @@ -132,7 +133,8 @@ namespace System // positive and 1 meaning negative. // // NOTE: Do not change the order in which these fields are declared. The - // native methods in this class rely on this particular order. + // native methods in this class rely on this particular order. + // Do not rename (binary serialization). private int flags; private int hi; private int lo; diff --git a/src/mscorlib/src/System/Double.cs b/src/mscorlib/src/System/Double.cs index 30fa1a58b3..b64bb72ed2 100644 --- a/src/mscorlib/src/System/Double.cs +++ b/src/mscorlib/src/System/Double.cs @@ -23,6 +23,7 @@ namespace System { [Serializable] [StructLayout(LayoutKind.Sequential)] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public struct Double : IComparable, IFormattable, IConvertible , IComparable, IEquatable { diff --git a/src/mscorlib/src/System/Enum.cs b/src/mscorlib/src/System/Enum.cs index 489f36739c..25a4ff34d3 100644 --- a/src/mscorlib/src/System/Enum.cs +++ b/src/mscorlib/src/System/Enum.cs @@ -15,6 +15,7 @@ using System.Diagnostics.Contracts; namespace System { [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public abstract class Enum : ValueType, IComparable, IFormattable, IConvertible { #region Private Constants diff --git a/src/mscorlib/src/System/Exception.cs b/src/mscorlib/src/System/Exception.cs index 8d01b4c461..725adac4a9 100644 --- a/src/mscorlib/src/System/Exception.cs +++ b/src/mscorlib/src/System/Exception.cs @@ -28,6 +28,7 @@ namespace System using System.Diagnostics.Contracts; [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public class Exception : ISerializable { private void Init() @@ -75,17 +76,17 @@ namespace System throw new ArgumentNullException(nameof(info)); Contract.EndContractBlock(); - _className = info.GetString("ClassName"); - _message = info.GetString("Message"); - _data = (IDictionary)(info.GetValueNoThrow("Data", typeof(IDictionary))); - _innerException = (Exception)(info.GetValue("InnerException", typeof(Exception))); - _helpURL = info.GetString("HelpURL"); - _stackTraceString = info.GetString("StackTraceString"); - _remoteStackTraceString = info.GetString("RemoteStackTraceString"); - _remoteStackIndex = info.GetInt32("RemoteStackIndex"); - - HResult = info.GetInt32("HResult"); - _source = info.GetString("Source"); + _className = info.GetString("ClassName"); // Do not rename (binary serialization) + _message = info.GetString("Message"); // Do not rename (binary serialization) + _data = (IDictionary)(info.GetValueNoThrow("Data", typeof(IDictionary))); // Do not rename (binary serialization) + _innerException = (Exception)(info.GetValue("InnerException", typeof(Exception))); // Do not rename (binary serialization) + _helpURL = info.GetString("HelpURL"); // Do not rename (binary serialization) + _stackTraceString = info.GetString("StackTraceString"); // Do not rename (binary serialization) + _remoteStackTraceString = info.GetString("RemoteStackTraceString"); // Do not rename (binary serialization) + _remoteStackIndex = info.GetInt32("RemoteStackIndex"); // Do not rename (binary serialization) + + HResult = info.GetInt32("HResult"); // Do not rename (binary serialization) + _source = info.GetString("Source"); // Do not rename (binary serialization) // Get the WatsonBuckets that were serialized - this is particularly // done to support exceptions going across AD transitions. @@ -93,7 +94,7 @@ namespace System // We use the no throw version since we could be deserializing a pre-V4 // exception object that may not have this entry. In such a case, we would // get null. - _watsonBuckets = (Object)info.GetValueNoThrow("WatsonBuckets", typeof(byte[])); + _watsonBuckets = (Object)info.GetValueNoThrow("WatsonBuckets", typeof(byte[])); // Do not rename (binary serialization) if (_className == null || HResult == 0) @@ -459,20 +460,20 @@ namespace System _source = Source; // Set the Source information correctly before serialization } - info.AddValue("ClassName", GetClassName(), typeof(String)); - info.AddValue("Message", _message, typeof(String)); - info.AddValue("Data", _data, typeof(IDictionary)); - info.AddValue("InnerException", _innerException, typeof(Exception)); - info.AddValue("HelpURL", _helpURL, typeof(String)); - info.AddValue("StackTraceString", tempStackTraceString, typeof(String)); - info.AddValue("RemoteStackTraceString", _remoteStackTraceString, typeof(String)); - info.AddValue("RemoteStackIndex", _remoteStackIndex, typeof(Int32)); - info.AddValue("ExceptionMethod", null, typeof(String)); - info.AddValue("HResult", HResult); - info.AddValue("Source", _source, typeof(String)); + info.AddValue("ClassName", GetClassName(), typeof(String)); // Do not rename (binary serialization) + info.AddValue("Message", _message, typeof(String)); // Do not rename (binary serialization) + info.AddValue("Data", _data, typeof(IDictionary)); // Do not rename (binary serialization) + info.AddValue("InnerException", _innerException, typeof(Exception)); // Do not rename (binary serialization) + info.AddValue("HelpURL", _helpURL, typeof(String)); // Do not rename (binary serialization) + info.AddValue("StackTraceString", tempStackTraceString, typeof(String)); // Do not rename (binary serialization) + info.AddValue("RemoteStackTraceString", _remoteStackTraceString, typeof(String)); // Do not rename (binary serialization) + info.AddValue("RemoteStackIndex", _remoteStackIndex, typeof(Int32)); // Do not rename (binary serialization) + info.AddValue("ExceptionMethod", null, typeof(String)); // Do not rename (binary serialization) + info.AddValue("HResult", HResult); // Do not rename (binary serialization) + info.AddValue("Source", _source, typeof(String)); // Do not rename (binary serialization) // Serialize the Watson bucket details as well - info.AddValue("WatsonBuckets", _watsonBuckets, typeof(byte[])); + info.AddValue("WatsonBuckets", _watsonBuckets, typeof(byte[])); // Do not rename (binary serialization) } // This method will clear the _stackTrace of the exception object upon deserialization diff --git a/src/mscorlib/src/System/Globalization/CompareInfo.Windows.cs b/src/mscorlib/src/System/Globalization/CompareInfo.Windows.cs index eb4dc5613e..0df5463a2f 100644 --- a/src/mscorlib/src/System/Globalization/CompareInfo.Windows.cs +++ b/src/mscorlib/src/System/Globalization/CompareInfo.Windows.cs @@ -469,6 +469,7 @@ namespace System.Globalization Debug.Assert(!_invariantMode); Interop.Kernel32.NlsVersionInfoEx nlsVersion = new Interop.Kernel32.NlsVersionInfoEx(); + nlsVersion.dwNLSVersionInfoSize = Marshal.SizeOf(typeof(Interop.Kernel32.NlsVersionInfoEx)); Interop.Kernel32.GetNLSVersionEx(Interop.Kernel32.COMPARE_STRING, _sortName, &nlsVersion); return new SortVersion( nlsVersion.dwNLSVersion, diff --git a/src/mscorlib/src/System/Globalization/CompareInfo.cs b/src/mscorlib/src/System/Globalization/CompareInfo.cs index 593e86415d..bfdbdc546b 100644 --- a/src/mscorlib/src/System/Globalization/CompareInfo.cs +++ b/src/mscorlib/src/System/Globalization/CompareInfo.cs @@ -34,6 +34,7 @@ namespace System.Globalization } [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public partial class CompareInfo : IDeserializationCallback { // Mask used to check if IndexOf()/LastIndexOf()/IsPrefix()/IsPostfix() has the right flags. @@ -69,11 +70,13 @@ namespace System.Globalization private string _sortName; // The name that defines our behavior. [OptionalField(VersionAdded = 3)] - private SortVersion m_sortVersion; // Do not rename (binary serialization) + private SortVersion m_SortVersion; // Do not rename (binary serialization) // _invariantMode is defined for the perf reason as accessing the instance field is faster than access the static property GlobalizationMode.Invariant [NonSerialized] private readonly bool _invariantMode = GlobalizationMode.Invariant; + + private int culture; // Do not rename (binary serialization). The fields sole purpose is to support Desktop serialization. internal CompareInfo(CultureInfo culture) { @@ -233,14 +236,26 @@ namespace System.Globalization private void OnDeserialized() { - if (m_name != null) + // If we didn't have a name, use the LCID + if (m_name == null) + { + // From whidbey, didn't have a name + CultureInfo ci = CultureInfo.GetCultureInfo(this.culture); + m_name = ci._name; + } + else { InitSort(CultureInfo.GetCultureInfo(m_name)); } } [OnSerializing] - private void OnSerializing(StreamingContext ctx) { } + private void OnSerializing(StreamingContext ctx) + { + // This is merely for serialization compatibility with Whidbey/Orcas, it can go away when we don't want that compat any more. + culture = CultureInfo.GetCultureInfo(this.Name).LCID; // This is the lcid of the constructing culture (still have to dereference to get target sort) + Contract.Assert(m_name != null, "CompareInfo.OnSerializing - expected m_name to be set already"); + } ///////////////////////////----- Name -----///////////////////////////////// // @@ -1208,11 +1223,11 @@ namespace System.Globalization { get { - if (m_sortVersion == null) + if (m_SortVersion == null) { if (_invariantMode) { - m_sortVersion = new SortVersion(0, CultureInfo.LOCALE_INVARIANT, new Guid(0, 0, 0, 0, 0, 0, 0, + m_SortVersion = new SortVersion(0, CultureInfo.LOCALE_INVARIANT, new Guid(0, 0, 0, 0, 0, 0, 0, (byte) (CultureInfo.LOCALE_INVARIANT >> 24), (byte) ((CultureInfo.LOCALE_INVARIANT & 0x00FF0000) >> 16), (byte) ((CultureInfo.LOCALE_INVARIANT & 0x0000FF00) >> 8), @@ -1220,11 +1235,11 @@ namespace System.Globalization } else { - m_sortVersion = GetSortVersion(); + m_SortVersion = GetSortVersion(); } } - return m_sortVersion; + return m_SortVersion; } } diff --git a/src/mscorlib/src/System/Globalization/CultureInfo.cs b/src/mscorlib/src/System/Globalization/CultureInfo.cs index 16e2d291a1..ee64bc52e2 100644 --- a/src/mscorlib/src/System/Globalization/CultureInfo.cs +++ b/src/mscorlib/src/System/Globalization/CultureInfo.cs @@ -206,6 +206,26 @@ namespace System.Globalization InitializeFromName(name, useUserOverride); } + private CultureInfo(CultureData cultureData) + { + Debug.Assert(cultureData != null); + _cultureData = cultureData; + _name = cultureData.CultureName; + _isInherited = false; + } + + private static CultureInfo CreateCultureInfoNoThrow(string name, bool useUserOverride) + { + Debug.Assert(name != null); + CultureData cultureData = CultureData.GetCultureData(name, useUserOverride); + if (cultureData == null) + { + return null; + } + + return new CultureInfo(cultureData); + } + public CultureInfo(int culture) : this(culture, true) { } @@ -533,25 +553,22 @@ namespace System.Globalization { if (null == _parent) { - try - { - string parentName = _cultureData.SPARENT; + string parentName = _cultureData.SPARENT; - if (String.IsNullOrEmpty(parentName)) + if (String.IsNullOrEmpty(parentName)) + { + _parent = InvariantCulture; + } + else + { + _parent = CreateCultureInfoNoThrow(parentName, _cultureData.UseUserOverride); + if (_parent == null) { + // For whatever reason our IPARENT or SPARENT wasn't correct, so use invariant + // We can't allow ourselves to fail. In case of custom cultures the parent of the + // current custom culture isn't installed. _parent = InvariantCulture; } - else - { - _parent = new CultureInfo(parentName, _cultureData.UseUserOverride); - } - } - catch (ArgumentException) - { - // For whatever reason our IPARENT or SPARENT wasn't correct, so use invariant - // We can't allow ourselves to fail. In case of custom cultures the parent of the - // current custom culture isn't installed. - _parent = InvariantCulture; } } return _parent; diff --git a/src/mscorlib/src/System/Guid.cs b/src/mscorlib/src/System/Guid.cs index f64211d5d0..e3b3a6f944 100644 --- a/src/mscorlib/src/System/Guid.cs +++ b/src/mscorlib/src/System/Guid.cs @@ -18,6 +18,7 @@ namespace System [StructLayout(LayoutKind.Sequential)] [Serializable] [System.Runtime.Versioning.NonVersionable] // This only applies to field layout + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public struct Guid : IFormattable, IComparable , IComparable, IEquatable { @@ -25,17 +26,17 @@ namespace System //////////////////////////////////////////////////////////////////////////////// // Member variables //////////////////////////////////////////////////////////////////////////////// - private int _a; - private short _b; - private short _c; - private byte _d; - private byte _e; - private byte _f; - private byte _g; - private byte _h; - private byte _i; - private byte _j; - private byte _k; + private int _a; // Do not rename (binary serialization) + private short _b; // Do not rename (binary serialization) + private short _c; // Do not rename (binary serialization) + private byte _d; // Do not rename (binary serialization) + private byte _e; // Do not rename (binary serialization) + private byte _f; // Do not rename (binary serialization) + private byte _g; // Do not rename (binary serialization) + private byte _h; // Do not rename (binary serialization) + private byte _i; // Do not rename (binary serialization) + private byte _j; // Do not rename (binary serialization) + private byte _k; // Do not rename (binary serialization) diff --git a/src/mscorlib/src/System/Int16.cs b/src/mscorlib/src/System/Int16.cs index aced05df6d..82e5dd5a38 100644 --- a/src/mscorlib/src/System/Int16.cs +++ b/src/mscorlib/src/System/Int16.cs @@ -22,6 +22,7 @@ namespace System { [Serializable] [System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public struct Int16 : IComparable, IFormattable, IConvertible , IComparable, IEquatable { diff --git a/src/mscorlib/src/System/Int32.cs b/src/mscorlib/src/System/Int32.cs index afee0e42d7..503552117d 100644 --- a/src/mscorlib/src/System/Int32.cs +++ b/src/mscorlib/src/System/Int32.cs @@ -22,6 +22,7 @@ namespace System { [Serializable] [System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public struct Int32 : IComparable, IFormattable, IConvertible , IComparable, IEquatable { diff --git a/src/mscorlib/src/System/Int64.cs b/src/mscorlib/src/System/Int64.cs index 619bf7e5d7..015387233c 100644 --- a/src/mscorlib/src/System/Int64.cs +++ b/src/mscorlib/src/System/Int64.cs @@ -21,6 +21,7 @@ namespace System { [Serializable] [System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public struct Int64 : IComparable, IFormattable, IConvertible , IComparable, IEquatable { diff --git a/src/mscorlib/src/System/IntPtr.cs b/src/mscorlib/src/System/IntPtr.cs index 55c86e3795..e3439801ff 100644 --- a/src/mscorlib/src/System/IntPtr.cs +++ b/src/mscorlib/src/System/IntPtr.cs @@ -23,9 +23,10 @@ namespace System using System.Diagnostics.Contracts; [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public struct IntPtr : IEquatable, ISerializable { - unsafe private void* _value; // The compiler treats void* closest to uint hence explicit casts are required to preserve int behavior + unsafe private void* _value; // The compiler treats void* closest to uint hence explicit casts are required to preserve int behavior. Do not rename (binary serialization) public static readonly IntPtr Zero; diff --git a/src/mscorlib/src/System/Nullable.cs b/src/mscorlib/src/System/Nullable.cs index 31a62ecea8..a2c7c350c9 100644 --- a/src/mscorlib/src/System/Nullable.cs +++ b/src/mscorlib/src/System/Nullable.cs @@ -23,10 +23,11 @@ namespace System // [Serializable] [System.Runtime.Versioning.NonVersionable] // This only applies to field layout + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public struct Nullable where T : struct { - private bool hasValue; - internal T value; + private bool hasValue; // Do not rename (binary serialization) + internal T value; // Do not rename (binary serialization) [System.Runtime.Versioning.NonVersionable] public Nullable(T value) diff --git a/src/mscorlib/src/System/Object.cs b/src/mscorlib/src/System/Object.cs index a476557911..8df1caa9e5 100644 --- a/src/mscorlib/src/System/Object.cs +++ b/src/mscorlib/src/System/Object.cs @@ -34,6 +34,7 @@ namespace System [Serializable] [ClassInterface(ClassInterfaceType.AutoDual)] [System.Runtime.InteropServices.ComVisible(true)] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public class Object { // Creates a new instance of an Object. diff --git a/src/mscorlib/src/System/Reflection/Assembly.CoreCLR.cs b/src/mscorlib/src/System/Reflection/Assembly.CoreCLR.cs index 9d34b48177..49a55181d4 100644 --- a/src/mscorlib/src/System/Reflection/Assembly.CoreCLR.cs +++ b/src/mscorlib/src/System/Reflection/Assembly.CoreCLR.cs @@ -52,7 +52,19 @@ namespace System.Reflection string requestedAssemblyPath = Path.Combine(Path.GetDirectoryName(requestorPath), requestedAssemblyName.Name+".dll"); // Load the dependency via LoadFrom so that it goes through the same path of being in the LoadFrom list. - return Assembly.LoadFrom(requestedAssemblyPath); + Assembly resolvedAssembly = null; + + try + { + resolvedAssembly = Assembly.LoadFrom(requestedAssemblyPath); + } + catch(FileNotFoundException) + { + // Catch FileNotFoundException when attempting to resolve assemblies via this handler to account for missing assemblies. + resolvedAssembly = null; + } + + return resolvedAssembly; } public static Assembly LoadFrom(String assemblyFile) diff --git a/src/mscorlib/src/System/Resources/LooselyLinkedResourceReference.cs b/src/mscorlib/src/System/Resources/LooselyLinkedResourceReference.cs deleted file mode 100644 index 3179df09b7..0000000000 --- a/src/mscorlib/src/System/Resources/LooselyLinkedResourceReference.cs +++ /dev/null @@ -1,85 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -/*============================================================ -** -** -** -** -** -** Purpose: Provides a localizable way of retrieving a file -** that is linked into your assembly and/or satellite assembly -** while also leaving the file on disk for unmanaged tools. -** -** -===========================================================*/ - -// Removing LooselyLinkedResourceReference from Whidbey. We don't -// yet have any strong customer need for it yet. -#if LOOSELY_LINKED_RESOURCE_REFERENCE - -namespace System.Resources { - using System.Reflection; - using System.Diagnostics.Contracts; - using System.IO; - using System.Runtime.InteropServices; - using System.Globalization; - - [Serializable] - - public struct LooselyLinkedResourceReference { - private String _manifestResourceName; - private String _typeName; - - public LooselyLinkedResourceReference(String looselyLinkedResourceName, String typeName) - { - if (looselyLinkedResourceName == null) - throw new ArgumentNullException(nameof(looselyLinkedResourceName)); - if (typeName == null) - throw new ArgumentNullException(nameof(typeName)); - if (looselyLinkedResourceName.Length == 0) - throw new ArgumentException(SR.Argument_EmptyName, nameof(looselyLinkedResourceName)); - if (typeName.Length == 0) - throw new ArgumentException(SR.Argument_EmptyName, nameof(typeName)); - Contract.EndContractBlock(); - - _manifestResourceName = looselyLinkedResourceName; - _typeName = typeName; - } - - public String LooselyLinkedResourceName { - get { return _manifestResourceName; } - } - - public String TypeName { - get { return _typeName; } - } - - public Object Resolve(Assembly assembly) - { - if (assembly == null) - throw new ArgumentNullException(nameof(assembly)); - Contract.EndContractBlock(); - - Stream data = assembly.GetManifestResourceStream(_manifestResourceName); - if (data == null) - throw new MissingManifestResourceException(SR.Format(SR.MissingManifestResource_LooselyLinked, _manifestResourceName, assembly.FullName)); - - Type type = Type.GetType(_typeName, true); - - Object obj = Activator.CreateInstance(type, new Object[] { data }); - return obj; - } - - // For good debugging with tools like ResView - public override String ToString() - { - // This is for debugging only. Since we use the property names, - // this does not need to be localized. - return "LooselyLinkedResourceName = \""+ _manifestResourceName +"\", TypeName = \"" + _typeName + "\""; - } - } -} - -#endif // LOOSELY_LINKED_RESOURCE_REFERENCE diff --git a/src/mscorlib/src/System/SByte.cs b/src/mscorlib/src/System/SByte.cs index 9e550936fe..8a0ab3e129 100644 --- a/src/mscorlib/src/System/SByte.cs +++ b/src/mscorlib/src/System/SByte.cs @@ -21,6 +21,7 @@ namespace System // A place holder class for signed bytes. [Serializable] [CLSCompliant(false), System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public struct SByte : IComparable, IFormattable, IConvertible , IComparable, IEquatable { diff --git a/src/mscorlib/src/System/Single.cs b/src/mscorlib/src/System/Single.cs index 24e6839be6..c94e673c26 100644 --- a/src/mscorlib/src/System/Single.cs +++ b/src/mscorlib/src/System/Single.cs @@ -22,6 +22,7 @@ namespace System { [Serializable] [System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public struct Single : IComparable, IFormattable, IConvertible , IComparable, IEquatable { diff --git a/src/mscorlib/src/System/String.cs b/src/mscorlib/src/System/String.cs index 0a17c1ee24..c2b7466d92 100644 --- a/src/mscorlib/src/System/String.cs +++ b/src/mscorlib/src/System/String.cs @@ -40,6 +40,7 @@ namespace System // (indices) are zero-based. [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public sealed partial class String : IComparable, ICloneable, IConvertible, IEnumerable , IComparable, IEnumerable, IEquatable { diff --git a/src/mscorlib/src/System/TimeSpan.cs b/src/mscorlib/src/System/TimeSpan.cs index 9166656d0f..ca60bcb16f 100644 --- a/src/mscorlib/src/System/TimeSpan.cs +++ b/src/mscorlib/src/System/TimeSpan.cs @@ -68,7 +68,7 @@ namespace System // internal so that DateTime doesn't have to call an extra get // method for some arithmetic operations. - internal long _ticks; + internal long _ticks; // Do not rename (binary serialization) //public TimeSpan() { // _ticks = 0; diff --git a/src/mscorlib/src/System/TimeZoneInfo.AdjustmentRule.cs b/src/mscorlib/src/System/TimeZoneInfo.AdjustmentRule.cs index c0c27eeab7..79fe8db815 100644 --- a/src/mscorlib/src/System/TimeZoneInfo.AdjustmentRule.cs +++ b/src/mscorlib/src/System/TimeZoneInfo.AdjustmentRule.cs @@ -212,13 +212,13 @@ namespace System } Contract.EndContractBlock(); - info.AddValue("DateStart", _dateStart); - info.AddValue("DateEnd", _dateEnd); - info.AddValue("DaylightDelta", _daylightDelta); - info.AddValue("DaylightTransitionStart", _daylightTransitionStart); - info.AddValue("DaylightTransitionEnd", _daylightTransitionEnd); - info.AddValue("BaseUtcOffsetDelta", _baseUtcOffsetDelta); - info.AddValue("NoDaylightTransitions", _noDaylightTransitions); + info.AddValue("DateStart", _dateStart); // Do not rename (binary serialization) + info.AddValue("DateEnd", _dateEnd); // Do not rename (binary serialization) + info.AddValue("DaylightDelta", _daylightDelta); // Do not rename (binary serialization) + info.AddValue("DaylightTransitionStart", _daylightTransitionStart); // Do not rename (binary serialization) + info.AddValue("DaylightTransitionEnd", _daylightTransitionEnd); // Do not rename (binary serialization) + info.AddValue("BaseUtcOffsetDelta", _baseUtcOffsetDelta); // Do not rename (binary serialization) + info.AddValue("NoDaylightTransitions", _noDaylightTransitions); // Do not rename (binary serialization) } private AdjustmentRule(SerializationInfo info, StreamingContext context) @@ -228,19 +228,19 @@ namespace System throw new ArgumentNullException(nameof(info)); } - _dateStart = (DateTime)info.GetValue("DateStart", typeof(DateTime)); - _dateEnd = (DateTime)info.GetValue("DateEnd", typeof(DateTime)); - _daylightDelta = (TimeSpan)info.GetValue("DaylightDelta", typeof(TimeSpan)); - _daylightTransitionStart = (TransitionTime)info.GetValue("DaylightTransitionStart", typeof(TransitionTime)); - _daylightTransitionEnd = (TransitionTime)info.GetValue("DaylightTransitionEnd", typeof(TransitionTime)); + _dateStart = (DateTime)info.GetValue("DateStart", typeof(DateTime)); // Do not rename (binary serialization) + _dateEnd = (DateTime)info.GetValue("DateEnd", typeof(DateTime)); // Do not rename (binary serialization) + _daylightDelta = (TimeSpan)info.GetValue("DaylightDelta", typeof(TimeSpan)); // Do not rename (binary serialization) + _daylightTransitionStart = (TransitionTime)info.GetValue("DaylightTransitionStart", typeof(TransitionTime)); // Do not rename (binary serialization) + _daylightTransitionEnd = (TransitionTime)info.GetValue("DaylightTransitionEnd", typeof(TransitionTime)); // Do not rename (binary serialization) - object o = info.GetValueNoThrow("BaseUtcOffsetDelta", typeof(TimeSpan)); + object o = info.GetValueNoThrow("BaseUtcOffsetDelta", typeof(TimeSpan)); // Do not rename (binary serialization) if (o != null) { _baseUtcOffsetDelta = (TimeSpan)o; } - o = info.GetValueNoThrow("NoDaylightTransitions", typeof(bool)); + o = info.GetValueNoThrow("NoDaylightTransitions", typeof(bool)); // Do not rename (binary serialization) if (o != null) { _noDaylightTransitions = (bool)o; diff --git a/src/mscorlib/src/System/TimeZoneInfo.TransitionTime.cs b/src/mscorlib/src/System/TimeZoneInfo.TransitionTime.cs index 1e1d9d328b..0fe3dab0b6 100644 --- a/src/mscorlib/src/System/TimeZoneInfo.TransitionTime.cs +++ b/src/mscorlib/src/System/TimeZoneInfo.TransitionTime.cs @@ -132,12 +132,12 @@ namespace System } Contract.EndContractBlock(); - info.AddValue("TimeOfDay", _timeOfDay); - info.AddValue("Month", _month); - info.AddValue("Week", _week); - info.AddValue("Day", _day); - info.AddValue("DayOfWeek", _dayOfWeek); - info.AddValue("IsFixedDateRule", _isFixedDateRule); + info.AddValue("TimeOfDay", _timeOfDay); // Do not rename (binary serialization) + info.AddValue("Month", _month); // Do not rename (binary serialization) + info.AddValue("Week", _week); // Do not rename (binary serialization) + info.AddValue("Day", _day); // Do not rename (binary serialization) + info.AddValue("DayOfWeek", _dayOfWeek); // Do not rename (binary serialization) + info.AddValue("IsFixedDateRule", _isFixedDateRule); // Do not rename (binary serialization) } private TransitionTime(SerializationInfo info, StreamingContext context) @@ -147,12 +147,12 @@ namespace System throw new ArgumentNullException(nameof(info)); } - _timeOfDay = (DateTime)info.GetValue("TimeOfDay", typeof(DateTime)); - _month = (byte)info.GetValue("Month", typeof(byte)); - _week = (byte)info.GetValue("Week", typeof(byte)); - _day = (byte)info.GetValue("Day", typeof(byte)); - _dayOfWeek = (DayOfWeek)info.GetValue("DayOfWeek", typeof(DayOfWeek)); - _isFixedDateRule = (bool)info.GetValue("IsFixedDateRule", typeof(bool)); + _timeOfDay = (DateTime)info.GetValue("TimeOfDay", typeof(DateTime)); // Do not rename (binary serialization) + _month = (byte)info.GetValue("Month", typeof(byte)); // Do not rename (binary serialization) + _week = (byte)info.GetValue("Week", typeof(byte)); // Do not rename (binary serialization) + _day = (byte)info.GetValue("Day", typeof(byte)); // Do not rename (binary serialization) + _dayOfWeek = (DayOfWeek)info.GetValue("DayOfWeek", typeof(DayOfWeek)); // Do not rename (binary serialization) + _isFixedDateRule = (bool)info.GetValue("IsFixedDateRule", typeof(bool)); // Do not rename (binary serialization) } } } diff --git a/src/mscorlib/src/System/TimeZoneInfo.cs b/src/mscorlib/src/System/TimeZoneInfo.cs index 8ed7e229c0..a492275a71 100644 --- a/src/mscorlib/src/System/TimeZoneInfo.cs +++ b/src/mscorlib/src/System/TimeZoneInfo.cs @@ -29,6 +29,7 @@ namespace System }; [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")] public sealed partial class TimeZoneInfo : IEquatable, ISerializable, IDeserializationCallback { private enum TimeZoneInfoResult @@ -1040,13 +1041,13 @@ namespace System } Contract.EndContractBlock(); - info.AddValue("Id", _id); - info.AddValue("DisplayName", _displayName); - info.AddValue("StandardName", _standardDisplayName); - info.AddValue("DaylightName", _daylightDisplayName); - info.AddValue("BaseUtcOffset", _baseUtcOffset); - info.AddValue("AdjustmentRules", _adjustmentRules); - info.AddValue("SupportsDaylightSavingTime", _supportsDaylightSavingTime); + info.AddValue("Id", _id); // Do not rename (binary serialization) + info.AddValue("DisplayName", _displayName); // Do not rename (binary serialization) + info.AddValue("StandardName", _standardDisplayName); // Do not rename (binary serialization) + info.AddValue("DaylightName", _daylightDisplayName); // Do not rename (binary serialization) + info.AddValue("BaseUtcOffset", _baseUtcOffset); // Do not rename (binary serialization) + info.AddValue("AdjustmentRules", _adjustmentRules); // Do not rename (binary serialization) + info.AddValue("SupportsDaylightSavingTime", _supportsDaylightSavingTime); // Do not rename (binary serialization) } private TimeZoneInfo(SerializationInfo info, StreamingContext context) @@ -1056,13 +1057,13 @@ namespace System throw new ArgumentNullException(nameof(info)); } - _id = (string)info.GetValue("Id", typeof(string)); - _displayName = (string)info.GetValue("DisplayName", typeof(string)); - _standardDisplayName = (string)info.GetValue("StandardName", typeof(string)); - _daylightDisplayName = (string)info.GetValue("DaylightName", typeof(string)); - _baseUtcOffset = (TimeSpan)info.GetValue("BaseUtcOffset", typeof(TimeSpan)); - _adjustmentRules = (AdjustmentRule[])info.GetValue("AdjustmentRules", typeof(AdjustmentRule[])); - _supportsDaylightSavingTime = (bool)info.GetValue("SupportsDaylightSavingTime", typeof(bool)); + _id = (string)info.GetValue("Id", typeof(string)); // Do not rename (binary serialization) + _displayName = (string)info.GetValue("DisplayName", typeof(string)); // Do not rename (binary serialization) + _standardDisplayName = (string)info.GetValue("StandardName", typeof(string)); // Do not rename (binary serialization) + _daylightDisplayName = (string)info.GetValue("DaylightName", typeof(string)); // Do not rename (binary serialization) + _baseUtcOffset = (TimeSpan)info.GetValue("BaseUtcOffset", typeof(TimeSpan)); // Do not rename (binary serialization) + _adjustmentRules = (AdjustmentRule[])info.GetValue("AdjustmentRules", typeof(AdjustmentRule[])); // Do not rename (binary serialization) + _supportsDaylightSavingTime = (bool)info.GetValue("SupportsDaylightSavingTime", typeof(bool)); // Do not rename (binary serialization) } private AdjustmentRule GetAdjustmentRuleForTime(DateTime dateTime, out int? ruleIndex) diff --git a/src/mscorlib/src/System/Tuple.cs b/src/mscorlib/src/System/Tuple.cs index a118df02bd..6a8758278c 100644 --- a/src/mscorlib/src/System/Tuple.cs +++ b/src/mscorlib/src/System/Tuple.cs @@ -105,9 +105,10 @@ namespace System } [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable, ITupleInternal, ITuple { - private readonly T1 m_Item1; + private readonly T1 m_Item1; // Do not rename (binary serialization) public T1 Item1 { get { return m_Item1; } } @@ -204,10 +205,11 @@ namespace System } [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable, ITupleInternal, ITuple { - private readonly T1 m_Item1; - private readonly T2 m_Item2; + private readonly T1 m_Item1; // Do not rename (binary serialization) + private readonly T2 m_Item2; // Do not rename (binary serialization) public T1 Item1 { get { return m_Item1; } } public T2 Item2 { get { return m_Item2; } } @@ -318,11 +320,12 @@ namespace System } [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable, ITupleInternal, ITuple { - private readonly T1 m_Item1; - private readonly T2 m_Item2; - private readonly T3 m_Item3; + private readonly T1 m_Item1; // Do not rename (binary serialization) + private readonly T2 m_Item2; // Do not rename (binary serialization) + private readonly T3 m_Item3; // Do not rename (binary serialization) public T1 Item1 { get { return m_Item1; } } public T2 Item2 { get { return m_Item2; } } @@ -443,12 +446,13 @@ namespace System } [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable, ITupleInternal, ITuple { - private readonly T1 m_Item1; - private readonly T2 m_Item2; - private readonly T3 m_Item3; - private readonly T4 m_Item4; + private readonly T1 m_Item1; // Do not rename (binary serialization) + private readonly T2 m_Item2; // Do not rename (binary serialization) + private readonly T3 m_Item3; // Do not rename (binary serialization) + private readonly T4 m_Item4; // Do not rename (binary serialization) public T1 Item1 { get { return m_Item1; } } public T2 Item2 { get { return m_Item2; } } @@ -579,13 +583,14 @@ namespace System } [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable, ITupleInternal, ITuple { - private readonly T1 m_Item1; - private readonly T2 m_Item2; - private readonly T3 m_Item3; - private readonly T4 m_Item4; - private readonly T5 m_Item5; + private readonly T1 m_Item1; // Do not rename (binary serialization) + private readonly T2 m_Item2; // Do not rename (binary serialization) + private readonly T3 m_Item3; // Do not rename (binary serialization) + private readonly T4 m_Item4; // Do not rename (binary serialization) + private readonly T5 m_Item5; // Do not rename (binary serialization) public T1 Item1 { get { return m_Item1; } } public T2 Item2 { get { return m_Item2; } } @@ -726,14 +731,15 @@ namespace System } [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable, ITupleInternal, ITuple { - private readonly T1 m_Item1; - private readonly T2 m_Item2; - private readonly T3 m_Item3; - private readonly T4 m_Item4; - private readonly T5 m_Item5; - private readonly T6 m_Item6; + private readonly T1 m_Item1; // Do not rename (binary serialization) + private readonly T2 m_Item2; // Do not rename (binary serialization) + private readonly T3 m_Item3; // Do not rename (binary serialization) + private readonly T4 m_Item4; // Do not rename (binary serialization) + private readonly T5 m_Item5; // Do not rename (binary serialization) + private readonly T6 m_Item6; // Do not rename (binary serialization) public T1 Item1 { get { return m_Item1; } } public T2 Item2 { get { return m_Item2; } } @@ -884,15 +890,16 @@ namespace System } [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable, ITupleInternal, ITuple { - private readonly T1 m_Item1; - private readonly T2 m_Item2; - private readonly T3 m_Item3; - private readonly T4 m_Item4; - private readonly T5 m_Item5; - private readonly T6 m_Item6; - private readonly T7 m_Item7; + private readonly T1 m_Item1; // Do not rename (binary serialization) + private readonly T2 m_Item2; // Do not rename (binary serialization) + private readonly T3 m_Item3; // Do not rename (binary serialization) + private readonly T4 m_Item4; // Do not rename (binary serialization) + private readonly T5 m_Item5; // Do not rename (binary serialization) + private readonly T6 m_Item6; // Do not rename (binary serialization) + private readonly T7 m_Item7; // Do not rename (binary serialization) public T1 Item1 { get { return m_Item1; } } public T2 Item2 { get { return m_Item2; } } @@ -1053,16 +1060,17 @@ namespace System } [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable, ITupleInternal, ITuple { - private readonly T1 m_Item1; - private readonly T2 m_Item2; - private readonly T3 m_Item3; - private readonly T4 m_Item4; - private readonly T5 m_Item5; - private readonly T6 m_Item6; - private readonly T7 m_Item7; - private readonly TRest m_Rest; + private readonly T1 m_Item1; // Do not rename (binary serialization) + private readonly T2 m_Item2; // Do not rename (binary serialization) + private readonly T3 m_Item3; // Do not rename (binary serialization) + private readonly T4 m_Item4; // Do not rename (binary serialization) + private readonly T5 m_Item5; // Do not rename (binary serialization) + private readonly T6 m_Item6; // Do not rename (binary serialization) + private readonly T7 m_Item7; // Do not rename (binary serialization) + private readonly TRest m_Rest; // Do not rename (binary serialization) public T1 Item1 { get { return m_Item1; } } public T2 Item2 { get { return m_Item2; } } diff --git a/src/mscorlib/src/System/UInt16.cs b/src/mscorlib/src/System/UInt16.cs index c7be2e9a1f..746ed7ba49 100644 --- a/src/mscorlib/src/System/UInt16.cs +++ b/src/mscorlib/src/System/UInt16.cs @@ -21,6 +21,7 @@ namespace System // Wrapper for unsigned 16 bit integers. [Serializable] [CLSCompliant(false), System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public struct UInt16 : IComparable, IFormattable, IConvertible , IComparable, IEquatable { diff --git a/src/mscorlib/src/System/UInt32.cs b/src/mscorlib/src/System/UInt32.cs index 2731047e06..f696816b98 100644 --- a/src/mscorlib/src/System/UInt32.cs +++ b/src/mscorlib/src/System/UInt32.cs @@ -23,6 +23,7 @@ namespace System // * Wrapper for unsigned 32 bit integers. [Serializable] [CLSCompliant(false), System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public struct UInt32 : IComparable, IFormattable, IConvertible , IComparable, IEquatable { diff --git a/src/mscorlib/src/System/UInt64.cs b/src/mscorlib/src/System/UInt64.cs index a54bb69ba4..03cdcc5f40 100644 --- a/src/mscorlib/src/System/UInt64.cs +++ b/src/mscorlib/src/System/UInt64.cs @@ -21,6 +21,7 @@ namespace System // Wrapper for unsigned 64 bit integers. [Serializable] [CLSCompliant(false), System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public struct UInt64 : IComparable, IFormattable, IConvertible , IComparable, IEquatable { diff --git a/src/mscorlib/src/System/UIntPtr.cs b/src/mscorlib/src/System/UIntPtr.cs index 08e494297b..1bed651e6f 100644 --- a/src/mscorlib/src/System/UIntPtr.cs +++ b/src/mscorlib/src/System/UIntPtr.cs @@ -21,9 +21,10 @@ namespace System [Serializable] [CLSCompliant(false)] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public struct UIntPtr : IEquatable, ISerializable { - unsafe private void* _value; + unsafe private void* _value; // Do not rename (binary serialization) public static readonly UIntPtr Zero; diff --git a/src/mscorlib/src/System/ValueType.cs b/src/mscorlib/src/System/ValueType.cs index 0cd08bd26f..e5b5528314 100644 --- a/src/mscorlib/src/System/ValueType.cs +++ b/src/mscorlib/src/System/ValueType.cs @@ -19,6 +19,7 @@ using System.Runtime.Versioning; namespace System { [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public abstract class ValueType { public override bool Equals(Object obj) diff --git a/src/mscorlib/src/System/WeakReference.cs b/src/mscorlib/src/System/WeakReference.cs index 60878b8e1c..a6a30c1978 100644 --- a/src/mscorlib/src/System/WeakReference.cs +++ b/src/mscorlib/src/System/WeakReference.cs @@ -20,6 +20,7 @@ using System.Diagnostics.Contracts; namespace System { [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public class WeakReference : ISerializable { // If you fix bugs here, please fix them in WeakReference at the same time. @@ -57,8 +58,8 @@ namespace System } Contract.EndContractBlock(); - Object target = info.GetValue("TrackedObject", typeof(Object)); - bool trackResurrection = info.GetBoolean("TrackResurrection"); + Object target = info.GetValue("TrackedObject", typeof(Object)); // Do not rename (binary serialization) + bool trackResurrection = info.GetBoolean("TrackResurrection"); // Do not rename (binary serialization) Create(target, trackResurrection); } @@ -108,8 +109,8 @@ namespace System throw new ArgumentNullException(nameof(info)); } Contract.EndContractBlock(); - info.AddValue("TrackedObject", Target, typeof(Object)); - info.AddValue("TrackResurrection", IsTrackResurrection()); + info.AddValue("TrackedObject", Target, typeof(Object)); // Do not rename (binary serialization) + info.AddValue("TrackResurrection", IsTrackResurrection()); // Do not rename (binary serialization) } [MethodImplAttribute(MethodImplOptions.InternalCall)] diff --git a/src/mscorlib/src/System/WeakReferenceOfT.cs b/src/mscorlib/src/System/WeakReferenceOfT.cs index fbb6f09098..7347683e2f 100644 --- a/src/mscorlib/src/System/WeakReferenceOfT.cs +++ b/src/mscorlib/src/System/WeakReferenceOfT.cs @@ -20,6 +20,7 @@ using System.Diagnostics.Contracts; namespace System { [Serializable] + [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] // This class is sealed to mitigate security issues caused by Object::MemberwiseClone. public sealed class WeakReference : ISerializable where T : class @@ -52,8 +53,8 @@ namespace System } Contract.EndContractBlock(); - T target = (T)info.GetValue("TrackedObject", typeof(T)); - bool trackResurrection = info.GetBoolean("TrackResurrection"); + T target = (T)info.GetValue("TrackedObject", typeof(T)); // Do not rename (binary serialization) + bool trackResurrection = info.GetBoolean("TrackResurrection"); // Do not rename (binary serialization) Create(target, trackResurrection); } @@ -105,8 +106,8 @@ namespace System } Contract.EndContractBlock(); - info.AddValue("TrackedObject", this.Target, typeof(T)); - info.AddValue("TrackResurrection", IsTrackResurrection()); + info.AddValue("TrackedObject", this.Target, typeof(T)); // Do not rename (binary serialization) + info.AddValue("TrackResurrection", IsTrackResurrection()); // Do not rename (binary serialization) } [MethodImplAttribute(MethodImplOptions.InternalCall)] diff --git a/src/mscorlib/src/mscorlib.Friends.cs b/src/mscorlib/src/mscorlib.Friends.cs index b02b4829d9..709ec21191 100644 --- a/src/mscorlib/src/mscorlib.Friends.cs +++ b/src/mscorlib/src/mscorlib.Friends.cs @@ -13,3 +13,5 @@ using System.Runtime.CompilerServices; // Depends on WindowsRuntimeImportAttribute [assembly: InternalsVisibleTo("System.Runtime.WindowsRuntime.UI.Xaml, PublicKey=00000000000000000400000000000000", AllInternalsVisible = false)] +// Cross framework serialization needs access to internals +[assembly: InternalsVisibleTo("mscorlib, PublicKey=00000000000000000400000000000000", AllInternalsVisible=false)] diff --git a/src/pal/src/exception/seh-unwind.cpp b/src/pal/src/exception/seh-unwind.cpp index ba43c2e725..7746bbbbf5 100644 --- a/src/pal/src/exception/seh-unwind.cpp +++ b/src/pal/src/exception/seh-unwind.cpp @@ -266,13 +266,8 @@ BOOL PAL_VirtualUnwind(CONTEXT *context, KNONVOLATILE_CONTEXT_POINTERS *contextP // cannot cross on some systems. if ((void*)curPc == g_SEHProcessExceptionReturnAddress) { - ULONG contextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT | CONTEXT_EXCEPTION_ACTIVE; - - #if defined(_AMD64_) - contextFlags |= CONTEXT_XSTATE; - #endif - size_t nativeContext = *(size_t*)(CONTEXTGetFP(context) + g_common_signal_handler_context_locvar_offset); - CONTEXTFromNativeContext((const native_context_t *)nativeContext, context, contextFlags); + CONTEXT* signalContext = (CONTEXT*)(CONTEXTGetFP(context) + g_common_signal_handler_context_locvar_offset); + memcpy_s(context, sizeof(CONTEXT), signalContext, sizeof(CONTEXT)); return TRUE; } diff --git a/src/pal/src/exception/signal.cpp b/src/pal/src/exception/signal.cpp index 57ae62ea21..10eecf7b02 100644 --- a/src/pal/src/exception/signal.cpp +++ b/src/pal/src/exception/signal.cpp @@ -411,7 +411,27 @@ extern "C" void signal_handler_worker(int code, siginfo_t *siginfo, void *contex // TODO: First variable parameter says whether a read (0) or write (non-0) caused the // fault. We must disassemble the instruction at record.ExceptionAddress // to correctly fill in this value. + + // Unmask the activation signal now that we are running on the original stack of the thread + sigset_t signal_set; + sigemptyset(&signal_set); + sigaddset(&signal_set, INJECT_ACTIVATION_SIGNAL); + + int sigmaskRet = pthread_sigmask(SIG_UNBLOCK, &signal_set, NULL); + if (sigmaskRet != 0) + { + ASSERT("pthread_sigmask failed; error number is %d\n", sigmaskRet); + } + returnPoint->returnFromHandler = common_signal_handler(code, siginfo, context, 2, (size_t)0, (size_t)siginfo->si_addr); + + // We are going to return to the alternate stack, so block the activation signal again + sigmaskRet = pthread_sigmask(SIG_BLOCK, &signal_set, NULL); + if (sigmaskRet != 0) + { + ASSERT("pthread_sigmask failed; error number is %d\n", sigmaskRet); + } + RtlRestoreContext(&returnPoint->context, NULL); } @@ -761,12 +781,13 @@ __attribute__((noinline)) static bool common_signal_handler(int code, siginfo_t *siginfo, void *sigcontext, int numParams, ...) { sigset_t signal_set; + CONTEXT signalContextRecord; CONTEXT *contextRecord; EXCEPTION_RECORD *exceptionRecord; native_context_t *ucontext; ucontext = (native_context_t *)sigcontext; - g_common_signal_handler_context_locvar_offset = (int)((char*)&ucontext - (char*)__builtin_frame_address(0)); + g_common_signal_handler_context_locvar_offset = (int)((char*)&signalContextRecord - (char*)__builtin_frame_address(0)); AllocateExceptionRecords(&exceptionRecord, &contextRecord); @@ -809,6 +830,9 @@ static bool common_signal_handler(int code, siginfo_t *siginfo, void *sigcontext } contextRecord->ContextFlags |= CONTEXT_EXCEPTION_ACTIVE; + + memcpy_s(&signalContextRecord, sizeof(CONTEXT), contextRecord, sizeof(CONTEXT)); + // The exception object takes ownership of the exceptionRecord and contextRecord PAL_SEHException exception(exceptionRecord, contextRecord); @@ -852,6 +876,16 @@ void handle_signal(int signal_id, SIGFUNC sigfunc, struct sigaction *previousAct #endif /* HAVE_SIGINFO_T */ sigemptyset(&newAction.sa_mask); +#ifdef INJECT_ACTIVATION_SIGNAL + if ((additionalFlags & SA_ONSTACK) != 0) + { + // A handler that runs on a separate stack should not be interrupted by the activation signal + // until it switches back to the regular stack, since that signal's handler would run on the + // limited separate stack and likely run into a stack overflow. + sigaddset(&newAction.sa_mask, INJECT_ACTIVATION_SIGNAL); + } +#endif + if (-1 == sigaction(signal_id, &newAction, previousAction)) { ASSERT("handle_signal: sigaction() call failed with error code %d (%s)\n", diff --git a/src/pal/src/thread/process.cpp b/src/pal/src/thread/process.cpp index 6db9bf6f51..e22d268cf6 100644 --- a/src/pal/src/thread/process.cpp +++ b/src/pal/src/thread/process.cpp @@ -2951,6 +2951,10 @@ PROCAbortInitialize() { *argv++ = "--triage"; } + else if (strcmp(envvar, "4") == 0) + { + *argv++ = "--full"; + } } envvar = getenv("COMPlus_CreateDumpDiagnostics"); diff --git a/src/pal/tools/gen-buildsys-clang.sh b/src/pal/tools/gen-buildsys-clang.sh index 944187786f..132be93c7d 100755 --- a/src/pal/tools/gen-buildsys-clang.sh +++ b/src/pal/tools/gen-buildsys-clang.sh @@ -173,8 +173,8 @@ cmake \ "-DCMAKE_NM=$llvm_nm" \ "-DCMAKE_OBJDUMP=$llvm_objdump" \ "-DCMAKE_BUILD_TYPE=$buildtype" \ - "-DCMAKE_ENABLE_CODE_COVERAGE=$code_coverage" \ "-DCMAKE_EXPORT_COMPILE_COMMANDS=1 " \ + "-DCLR_CMAKE_ENABLE_CODE_COVERAGE=$code_coverage" \ "-DCLR_CMAKE_BUILD_TESTS=$build_tests" \ $cmake_extra_defines \ $__UnprocessedCMakeArgs \ diff --git a/src/scripts/genEventPipe.py b/src/scripts/genEventPipe.py index a00511d95d..4c802acaf3 100644 --- a/src/scripts/genEventPipe.py +++ b/src/scripts/genEventPipe.py @@ -262,6 +262,8 @@ def generateEventPipeCmakeFile(etwmanifest, eventpipe_directory): topCmake.write(' "eventpipehelpers.cpp"\n') topCmake.write(""" ) + add_dependencies(eventpipe GeneratedEventingFiles) + # Install the static eventpipe library install(TARGETS eventpipe DESTINATION lib) """) diff --git a/src/vm/gcenv.ee.cpp b/src/vm/gcenv.ee.cpp index 63c4ffea10..c38419807f 100644 --- a/src/vm/gcenv.ee.cpp +++ b/src/vm/gcenv.ee.cpp @@ -1325,10 +1325,13 @@ void GCToEEInterface::StompWriteBarrier(WriteBarrierParameters* args) VolatileStore(&g_highest_address, args->highest_address); ::StompWriteBarrierResize(true, false); - // g_ephemeral_low/high aren't needed for the write barrier stomp, but they - // are needed in other places. + // StompWriteBarrierResize does not necessarily bash g_ephemeral_low + // usages, so we must do so here. This is particularly true on x86, + // where StompWriteBarrierResize will not bash g_ephemeral_low when + // called with the parameters (true, false), as it is above. g_ephemeral_low = args->ephemeral_low; g_ephemeral_high = args->ephemeral_high; + ::StompWriteBarrierEphemeral(true); return; case WriteBarrierOp::SwitchToWriteWatch: #ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP diff --git a/src/vm/object.cpp b/src/vm/object.cpp index 3e3f6d120a..4c08f0254e 100644 --- a/src/vm/object.cpp +++ b/src/vm/object.cpp @@ -2954,8 +2954,9 @@ void __fastcall ZeroMemoryInGCHeap(void* mem, size_t size) *memBytes++ = 0; // now write pointer sized pieces + // volatile ensures that this doesn't get optimized back into a memset call (see #12207) size_t nPtrs = (endBytes - memBytes) / sizeof(PTR_PTR_VOID); - PTR_PTR_VOID memPtr = (PTR_PTR_VOID) memBytes; + volatile PTR_PTR_VOID memPtr = (PTR_PTR_VOID) memBytes; for (size_t i = 0; i < nPtrs; i++) *memPtr++ = 0; -- cgit v1.2.3