Пример #1
0
        /// <summary>
        /// based on <a href="https://github.com/dotnet/coreclr/blob/master/src/gcdump/i386/gcdumpx86.cpp">GCDump::DumpGCTable</a>
        /// </summary>
        private void SaveCallTransition(byte[] image, ref int offset, uint val, uint curOffs, uint callRegMask, bool callPndTab, uint callPndTabCnt, uint callPndMask, uint lastSkip, ref uint imask)
        {
            uint iregMask, iargMask;

            iregMask = imask & 0xF;
            iargMask = imask >> 4;

            GcTransitionCall transition = new GcTransitionCall((int)curOffs, Header.EbpFrame, callRegMask, iregMask);

            AddNewTransition(transition);

            if (callPndTab)
            {
                for (int i = 0; i < callPndTabCnt; i++)
                {
                    uint pndOffs = NativeReader.DecodeUnsignedGc(image, ref offset);

                    uint stkOffs = val & ~byref_OFFSET_FLAG;
                    uint lowBit  = val & byref_OFFSET_FLAG;
                    transition.PtrArgs.Add(new GcTransitionCall.PtrArg(pndOffs, 0));
                }
            }
            else
            {
                if (callPndMask != 0)
                {
                    transition.ArgMask = callPndMask;
                }
                if (iargMask != 0)
                {
                    transition.IArgs = iargMask;
                }
            }

            imask = lastSkip = 0;
        }
Пример #2
0
        /// <summary>
        /// based on <a href="https://github.com/dotnet/coreclr/blob/master/src/gcdump/i386/gcdumpx86.cpp">GCDump::DumpGCTable</a>
        /// </summary>
        private void GetTransitionsEbpFrame(byte[] image, ref int offset)
        {
            while (true)
            {
                uint argMask = 0, byrefArgMask = 0;
                uint regMask, byrefRegMask = 0;

                uint argCnt    = 0;
                int  argOffset = offset;
                uint argTabSize;

                uint val, nxt;
                uint curOffs = 0;

                // Get the next byte and check for a 'special' entry
                uint             encType    = image[offset++];
                GcTransitionCall transition = null;

                switch (encType)
                {
                default:
                    // A tiny or small call entry
                    val = encType;

                    if ((val & 0x80) == 0x00)
                    {
                        if ((val & 0x0F) != 0)
                        {
                            // A tiny call entry

                            curOffs += (val & 0x0F);
                            regMask  = (val & 0x70) >> 4;
                            argMask  = 0;
                        }
                        else
                        {
                            Registers reg;
                            if ((val & 0x10) != 0)
                            {
                                reg = Registers.EDI;
                            }
                            else if ((val & 0x20) != 0)
                            {
                                reg = Registers.ESI;
                            }
                            else if ((val & 0x40) != 0)
                            {
                                reg = Registers.EBX;
                            }
                            else
                            {
                                throw new BadImageFormatException("Invalid register");
                            }
                            transition = new GcTransitionCall((int)curOffs);
                            transition.CallRegisters.Add(new GcTransitionCall.CallRegister(reg, false));
                            AddNewTransition(transition);

                            continue;
                        }
                    }
                    else
                    {
                        // A small call entry
                        curOffs += (val & 0x7F);
                        val      = image[offset++];
                        regMask  = val >> 5;
                        argMask  = val & 0x1F;
                    }
                    break;

                case 0xFD:      // medium encoding
                    argMask  = image[offset++];
                    val      = image[offset++];
                    argMask |= (val & 0xF0) << 4;
                    nxt      = image[offset++];
                    curOffs += (val & 0x0F) + ((nxt & 0x1F) << 4);
                    regMask  = nxt >> 5;                      // EBX,ESI,EDI
                    break;

                case 0xF9:      // medium encoding with byrefs
                    curOffs     += image[offset++];
                    val          = image[offset++];
                    argMask      = val & 0x1F;
                    regMask      = val >> 5;
                    val          = image[offset++];
                    byrefArgMask = val & 0x1F;
                    byrefRegMask = val >> 5;
                    break;

                case 0xFE:      // large encoding
                case 0xFA:      // large encoding with byrefs
                    val          = image[offset++];
                    regMask      = val & 0x7;
                    byrefRegMask = val >> 4;

                    curOffs += NativeReader.ReadUInt32(image, ref offset);
                    argMask  = NativeReader.ReadUInt32(image, ref offset);
                    if (encType == 0xFA)     // read byrefArgMask
                    {
                        byrefArgMask = NativeReader.ReadUInt32(image, ref offset);
                    }
                    break;

                case 0xFB:      // huge encoding
                    val          = image[offset++];
                    regMask      = val & 0x7;
                    byrefRegMask = val >> 4;
                    curOffs      = NativeReader.ReadUInt32(image, ref offset);
                    argCnt       = NativeReader.ReadUInt32(image, ref offset);
                    argTabSize   = NativeReader.ReadUInt32(image, ref offset);
                    argOffset    = offset;
                    offset      += (int)argTabSize;
                    break;

                case 0xFF:
                    return;
                }

                /*
                 *  Here we have the following values:
                 *
                 *  curOffs      ...    the code offset of the call
                 *  regMask      ...    mask of live pointer register variables
                 *  argMask      ...    bitmask of pushed pointer arguments
                 *  byrefRegMask ...    byref qualifier for regMask
                 *  byrefArgMask ...    byrer qualifier for argMask
                 */
                transition = new GcTransitionCall((int)curOffs, Header.EbpFrame, regMask, byrefRegMask);
                AddNewTransition(transition);

                if (argCnt != 0)
                {
                    do
                    {
                        val = NativeReader.DecodeUnsignedGc(image, ref argOffset);

                        uint stkOffs = val & ~byref_OFFSET_FLAG;
                        uint lowBit  = val & byref_OFFSET_FLAG;
                        transition.PtrArgs.Add(new GcTransitionCall.PtrArg(stkOffs, lowBit));
                    }while (--argCnt > 0);
                }
                else
                {
                    transition.ArgMask = argMask;
                    if (byrefArgMask != 0)
                    {
                        transition.IArgs = byrefArgMask;
                    }
                }
            }
        }