internal static int GetTlsSlotForThread(RuntimeBase runtime, ulong teb) { const int maxTlsSlot = 64; const int tlsSlotOffset = 0x1480; // Same on x86 and amd64 const int tlsExpansionSlotsOffset = 0x1780; uint ptrSize = (uint)runtime.PointerSize; ulong lowerTlsSlots = teb + tlsSlotOffset; uint clrTlsSlot = runtime.GetTlsSlot(); if (clrTlsSlot == uint.MaxValue) { return(0); } ulong tlsSlot = 0; if (clrTlsSlot < maxTlsSlot) { tlsSlot = lowerTlsSlots + ptrSize * clrTlsSlot; } else { if (!runtime.ReadPointer(teb + tlsExpansionSlotsOffset, out tlsSlot) || tlsSlot == 0) { return(0); } tlsSlot += ptrSize * (clrTlsSlot - maxTlsSlot); } ulong clrTls = 0; if (!runtime.ReadPointer(tlsSlot, out clrTls)) { return(0); } // Get thread data; uint tlsThreadTypeIndex = runtime.GetThreadTypeIndex(); if (tlsThreadTypeIndex == uint.MaxValue) { return(0); } ulong threadType = 0; if (!runtime.ReadPointer(clrTls + ptrSize * tlsThreadTypeIndex, out threadType)) { return(0); } return((int)threadType); }
internal static int GetTlsSlotForThread(RuntimeBase runtime, ulong teb) { const int maxTlsSlot = 64; const int tlsSlotOffset = 0x1480; // Same on x86 and amd64 const int tlsExpansionSlotsOffset = 0x1780; uint ptrSize = (uint)runtime.PointerSize; ulong lowerTlsSlots = teb + tlsSlotOffset; uint clrTlsSlot = runtime.GetTlsSlot(); if (clrTlsSlot == uint.MaxValue) return 0; ulong tlsSlot = 0; if (clrTlsSlot < maxTlsSlot) { tlsSlot = lowerTlsSlots + ptrSize * clrTlsSlot; } else { if (!runtime.ReadPointer(teb + tlsExpansionSlotsOffset, out tlsSlot) || tlsSlot == 0) return 0; tlsSlot += ptrSize * (clrTlsSlot - maxTlsSlot); } ulong clrTls = 0; if (!runtime.ReadPointer(tlsSlot, out clrTls)) return 0; // Get thread data; uint tlsThreadTypeIndex = runtime.GetThreadTypeIndex(); if (tlsThreadTypeIndex == uint.MaxValue) return 0; ulong threadType = 0; if (!runtime.ReadPointer(clrTls + ptrSize * tlsThreadTypeIndex, out threadType)) return 0; return (int)threadType; }
private static uint HashStaticDefineList(RuntimeBase runtime, IntPtr baseAddress, uint hash) { var valueType = 4; while (true) { var type = runtime.ReadValueU32(baseAddress); if (type == 0) { break; } switch (type) { case 1: { valueType = 1; baseAddress += 8; break; } case 2: { valueType = 2; baseAddress += 8; break; } case 3: { var listAddress = runtime.ReadPointer(baseAddress + 4); baseAddress += 8; if (listAddress != IntPtr.Zero) { hash = HashKeyValueList(runtime, listAddress, hash); } break; } case 5: { var parent = runtime.ReadPointer(baseAddress + 4); return(HashStaticDefineList(runtime, parent, hash)); } default: { // TODO(gibbed): FIXME var name = runtime.ReadStringZ(new IntPtr(type), Encoding.ASCII); hash = Adler32.Hash(name, hash); switch (valueType) { case 1: { var value = runtime.ReadValueU32(baseAddress + 4); hash = Adler32.Hash(value, hash); baseAddress += 8; break; } case 2: { var value = runtime.ReadStringZ(baseAddress + 4, Encoding.ASCII); hash = Adler32.Hash(value, hash); baseAddress += 8; break; } default: { throw new NotImplementedException(); } } break; } } } return(hash); }