home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 242 / Issue 242 - April 2008 - DPCS0408DVD.ISO / Software Money Savers / VirtualDub / Source / VirtualDub-1.7.7-src.7z / src / system / source / debugx86.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2006-11-05  |  5.1 KB  |  155 lines

  1. //    VirtualDub - Video processing and capture application
  2. //    System library component
  3. //    Copyright (C) 1998-2004 Avery Lee, All Rights Reserved.
  4. //
  5. //    Beginning with 1.6.0, the VirtualDub system library is licensed
  6. //    differently than the remainder of VirtualDub.  This particular file is
  7. //    thus licensed as follows (the "zlib" license):
  8. //
  9. //    This software is provided 'as-is', without any express or implied
  10. //    warranty.  In no event will the authors be held liable for any
  11. //    damages arising from the use of this software.
  12. //
  13. //    Permission is granted to anyone to use this software for any purpose,
  14. //    including commercial applications, and to alter it and redistribute it
  15. //    freely, subject to the following restrictions:
  16. //
  17. //    1.    The origin of this software must not be misrepresented; you must
  18. //        not claim that you wrote the original software. If you use this
  19. //        software in a product, an acknowledgment in the product
  20. //        documentation would be appreciated but is not required.
  21. //    2.    Altered source versions must be plainly marked as such, and must
  22. //        not be misrepresented as being the original software.
  23. //    3.    This notice may not be removed or altered from any source
  24. //        distribution.
  25.  
  26. #include "stdafx.h"
  27. #include <vd2/system/vdtypes.h>
  28. #include <vd2/system/debugx86.h>
  29.  
  30. bool VDIsValidCallX86(const char *buf, int len) {
  31.     // Permissible CALL sequences that we care about:
  32.     //
  33.     //    E8 xx xx xx xx            CALL near relative
  34.     //    FF (group 2)            CALL near absolute indirect
  35.     //
  36.     // Minimum sequence is 2 bytes (call eax).
  37.     // Maximum sequence is 7 bytes (call dword ptr [eax+disp32]).
  38.  
  39.     if (len >= 5 && buf[-5] == (char)0xE8)
  40.         return true;
  41.  
  42.     // FF 14 xx                    CALL [reg32+reg32*scale]
  43.  
  44.     if (len >= 3 && buf[-3] == (char)0xFF && buf[-2]==0x14)
  45.         return true;
  46.  
  47.     // FF 15 xx xx xx xx        CALL disp32
  48.  
  49.     if (len >= 6 && buf[-6] == (char)0xFF && buf[-5]==0x15)
  50.         return true;
  51.  
  52.     // FF 00-3F(!14/15)            CALL [reg32]
  53.  
  54.     if (len >= 2 && buf[-2] == (char)0xFF && (unsigned char)buf[-1] < 0x40)
  55.         return true;
  56.  
  57.     // FF D0-D7                    CALL reg32
  58.  
  59.     if (len >= 2 && buf[-2] == (char)0xFF && (buf[-1]&0xF8) == 0xD0)
  60.         return true;
  61.  
  62.     // FF 50-57 xx                CALL [reg32+reg32*scale+disp8]
  63.  
  64.     if (len >= 3 && buf[-3] == (char)0xFF && (buf[-2]&0xF8) == 0x50)
  65.         return true;
  66.  
  67.     // FF 90-97 xx xx xx xx xx    CALL [reg32+reg32*scale+disp32]
  68.  
  69.     if (len >= 7 && buf[-7] == (char)0xFF && (buf[-6]&0xF8) == 0x90)
  70.         return true;
  71.  
  72.     return false;
  73. }
  74.  
  75. VDInstructionTypeX86 VDGetInstructionTypeX86(const void *p) {
  76.     struct local {
  77.         static bool RangeHitTest(const uint8 *range, uint8 c) {
  78.             while(*range) {
  79.                 if (c>=range[0] && c<=range[1])
  80.                     return true;
  81.                 range += 2;
  82.             }
  83.  
  84.             return false;
  85.         }
  86.     };
  87.  
  88.     VDInstructionTypeX86 type = kX86InstUnknown;
  89.  
  90.     __try {
  91.         unsigned char buf[8];
  92.  
  93.         memcpy(buf, p, 8);
  94.  
  95.         if (buf[0] == 0x0f && buf[1] == 0x0f)
  96.             type = kX86Inst3DNow;            // Conveniently, all 3DNow! instructions begin 0F 0F
  97.         else if ((buf[0] == 0xdb || buf[0] == 0xdf) && (buf[1]>=0xe8 && buf[1]<=0xf7))
  98.             type = kX86InstP6;                // DB/DF E8-F7: FCOMI/FCOMIP/FUCOMI/FUCOMIP (P6)
  99.         else if ((buf[0]&0xfe)==0xda && (buf[1]&0xe0)==0xc0)
  100.             type = kX86InstP6;                // DA/DB C0-DF: FCMOVcc (P6)
  101.         else if (buf[0] == 0x0f && (buf[1]&0xf0)==0x40)
  102.             type = kX86InstP6;                // 0F 40-4F: CMOVcc (P6)
  103.         else {
  104.             const unsigned char *s = buf;
  105.             bool bWide = false;
  106.             bool bRepF2 = false;
  107.             bool bRepF3 = false;
  108.  
  109.             // At this point we're down to MMX, SSE, SSE2 -- which makes things simpler
  110.             // as we must see F2 0F, F3 0F, or 0F next.  MMX ops use 0F exclusively,
  111.             // some SSE ops use F2, and a few SSE2 ones use F3.  If we see 66 on an
  112.             // MMX or SSE op it's automatically SSE2 as it's either a 128-bit MMX op
  113.             // or a double-precision version of an SSE one.
  114.  
  115.             if (*s == 0x66) {        // 66h override used by SSE2 and is supposed to be ahead of F2/F3 in encodings
  116.                 ++s;
  117.                 bWide = true;
  118.             }
  119.  
  120.             if (*s == 0xf2) {
  121.                 ++s;
  122.                 bRepF2 = true;
  123.             }
  124.  
  125.             if (*s == 0xf3) {
  126.                 ++s;
  127.                 bRepF3 = true;
  128.             }
  129.  
  130.             if (*s++ == 0x0f) {
  131.                 // SSE - 1x, 28-2F, 5x, C2, AE
  132.                 // MMX2 - 70, C4-C6, D7, DA, DE, E0, E3, E4, E7, EA, EE, F6, F7
  133.                 // MMX - 6x, 7x, Dx, Ex, and Fx except for MMX2
  134.                 // SSE2 - C3, SSE ops with 66 or F2, MMX/MMX2 ops with 66/F2/F3
  135.  
  136.                 static const uint8 sse_ranges[]={0x10,0x1f,0x28,0x2f,0x50,0x5f,0xc2,0xc2,0xae,0xae,0};
  137.                 static const uint8 sse2_ranges[]={0xc3,0xc3,0};
  138.                 static const uint8 mmx2_ranges[]={0x70,0x70,0xc4,0xc6,0xd7,0xd7,0xda,0xda,0xde,0xde,0xe0,0xe0,0xe3,0xe4,0xe7,0xe7,0xea,0xea,0xee,0xee,0xf6,0xf7,0};
  139.                 static const uint8 mmx_ranges[]={0x60,0x7f,0xd0,0xff,0};
  140.  
  141.                 if (local::RangeHitTest(sse_ranges, *s))
  142.                     type = (bWide||bRepF2) ? kX86InstSSE2 : kX86InstSSE;
  143.                 else if (local::RangeHitTest(sse2_ranges, *s))
  144.                     type = kX86InstSSE2;
  145.                 else if (local::RangeHitTest(mmx2_ranges, *s))
  146.                     type = (bWide||bRepF2||bRepF3) ? kX86InstSSE2 : kX86InstMMX2;
  147.                 else if (local::RangeHitTest(mmx_ranges, *s))
  148.                     type = (bWide||bRepF2||bRepF3) ? kX86InstSSE2 : kX86InstMMX;
  149.             }
  150.         }
  151.     } __except(1) {
  152.     }
  153.     return type;
  154. }
  155.