tstLdrDisasmTest.cpp revision 99cd1ce586a12bf6b8c6084cbcdebe8fe3553cc2
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync/* $Id$ */
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync/** @file
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync * IPRT - RTLdr test object.
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync *
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync * We use precompiled versions of this object for testing all the loaders.
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync *
e64031e20c39650a7bc902a3e1aba613b9415deevboxsync * This is not supposed to be pretty or usable code, just something which
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync * make life difficult for the loader.
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync */
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync/*
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync * Copyright (C) 2006-2007 Oracle Corporation
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync *
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync * available from http://www.virtualbox.org. This file is free software;
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync * you can redistribute it and/or modify it under the terms of the GNU
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync * General Public License (GPL) as published by the Free Software
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync *
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync * The contents of this file may alternatively be used under the terms
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync * of the Common Development and Distribution License Version 1.0
2531fa93e6b9dd1b60eac57f360a47e38aaf4d41vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync * VirtualBox OSE distribution, in which case the provisions of the
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync * CDDL are applicable instead of those of the GPL.
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync *
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync * You may elect to license modified versions of this file under the
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync * terms and conditions of either the GPL or the CDDL or both.
bf27591c0d413dd4d7ba41cf89f117171968d462vboxsync */
b26de2ddb274b0e52de6652ad8b45259be2b9913vboxsync
3e88c818fff5c64b5eff43d5daf4596bd87230c5vboxsync
3e88c818fff5c64b5eff43d5daf4596bd87230c5vboxsync
3eef103be36a8f4828d69cfec3cea9bcefc9fd92vboxsync/*******************************************************************************
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync* Header Files *
f5e53763b0a581b0299e98028c6c52192eb06785vboxsync*******************************************************************************/
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync#include <VBox/dis.h>
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync#include <VBox/disopcode.h>
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync#include <iprt/string.h>
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync#if defined(IN_RING0) && !defined(RT_OS_WINDOWS) /* Too lazy to make import libs. */
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsyncextern "C" DECLIMPORT(int) MyPrintf(const char *pszFormat, ...);
34b5a73592441cbfacb85c2f2261648c1d25ad31vboxsync# define MY_PRINTF(a) MyPrintf a
34b5a73592441cbfacb85c2f2261648c1d25ad31vboxsync#else
34b5a73592441cbfacb85c2f2261648c1d25ad31vboxsync# define MY_PRINTF(a) do {} while (0)
34b5a73592441cbfacb85c2f2261648c1d25ad31vboxsync#endif
34b5a73592441cbfacb85c2f2261648c1d25ad31vboxsync
34b5a73592441cbfacb85c2f2261648c1d25ad31vboxsync
34b5a73592441cbfacb85c2f2261648c1d25ad31vboxsync/*******************************************************************************
34b5a73592441cbfacb85c2f2261648c1d25ad31vboxsync* Global Variables *
34b5a73592441cbfacb85c2f2261648c1d25ad31vboxsync*******************************************************************************/
34b5a73592441cbfacb85c2f2261648c1d25ad31vboxsync
34b5a73592441cbfacb85c2f2261648c1d25ad31vboxsync/* 32-bit code */
34b5a73592441cbfacb85c2f2261648c1d25ad31vboxsyncstatic const uint8_t g_ab32BitCode[] =
34b5a73592441cbfacb85c2f2261648c1d25ad31vboxsync{
b26de2ddb274b0e52de6652ad8b45259be2b9913vboxsync 0x55, // 1000ab50 55 push ebp
b26de2ddb274b0e52de6652ad8b45259be2b9913vboxsync 0x8b,0xec, // 1000ab51 8bec mov ebp,esp
b26de2ddb274b0e52de6652ad8b45259be2b9913vboxsync 0x8b,0x45,0x08, // 1000ab53 8b4508 mov eax,dword ptr [ebp+8]
b26de2ddb274b0e52de6652ad8b45259be2b9913vboxsync 0x81,0x38,0x07,0x07,// 1000ab56 813807076419 cmp dword ptr [eax],19640707h
b26de2ddb274b0e52de6652ad8b45259be2b9913vboxsync 0x64,0x19,
34b5a73592441cbfacb85c2f2261648c1d25ad31vboxsync 0x75,0x09, // 1000ab5c 7509 jne kLdr!kLdrModMap+0x17 (1000ab67)
34b5a73592441cbfacb85c2f2261648c1d25ad31vboxsync 0x8b,0x4d,0x08, // 1000ab5e 8b4d08 mov ecx,dword ptr [ebp+8]
b26de2ddb274b0e52de6652ad8b45259be2b9913vboxsync 0x83,0x79,0x2c,0x00,// 1000ab61 83792c00 cmp dword ptr [ecx+2Ch],0
a98c2afd05b2949737f73ec954d227712f3b0146vboxsync 0x75,0x07, // 1000ab65 7507 jne kLdr!kLdrModMap+0x1e (1000ab6e)
b26de2ddb274b0e52de6652ad8b45259be2b9913vboxsync 0xb8,0xc0,0x68,0x06,// 1000ab67 b8c0680600 mov eax,668C0h
a98c2afd05b2949737f73ec954d227712f3b0146vboxsync 0x00,
b26de2ddb274b0e52de6652ad8b45259be2b9913vboxsync 0xeb,0x14, // 1000ab6c eb14 jmp kLdr!kLdrModMap+0x32 (1000ab82)
a98c2afd05b2949737f73ec954d227712f3b0146vboxsync 0x33,0xd2, // 1000ab6e 33d2 xor edx,edx
b26de2ddb274b0e52de6652ad8b45259be2b9913vboxsync 0x75,0xe1, // 1000ab70 75e1 jne kLdr!kLdrModMap+0x3 (1000ab53)
a98c2afd05b2949737f73ec954d227712f3b0146vboxsync 0x8b,0x45,0x08, // 1000ab72 8b4508 mov eax,dword ptr [ebp+8]
b26de2ddb274b0e52de6652ad8b45259be2b9913vboxsync 0x50, // 1000ab75 50 push eax
a98c2afd05b2949737f73ec954d227712f3b0146vboxsync 0x8b,0x4d,0x08, // 1000ab76 8b4d08 mov ecx,dword ptr [ebp+8]
3e88c818fff5c64b5eff43d5daf4596bd87230c5vboxsync 0x8b,0x51,0x2c, // 1000ab79 8b512c mov edx,dword ptr [ecx+2Ch]
a98c2afd05b2949737f73ec954d227712f3b0146vboxsync 0xff,0x52,0x3c, // 1000ab7c ff523c call dword ptr [edx+3Ch]
a98c2afd05b2949737f73ec954d227712f3b0146vboxsync 0x83,0xc4,0x04, // 1000ab7f 83c404 add esp,4
a98c2afd05b2949737f73ec954d227712f3b0146vboxsync 0x5d, // 1000ab82 5d pop ebp
a98c2afd05b2949737f73ec954d227712f3b0146vboxsync 0xc3, // 1000ab83 c3 ret
a98c2afd05b2949737f73ec954d227712f3b0146vboxsync 0xcc
2531fa93e6b9dd1b60eac57f360a47e38aaf4d41vboxsync};
2531fa93e6b9dd1b60eac57f360a47e38aaf4d41vboxsync
b26de2ddb274b0e52de6652ad8b45259be2b9913vboxsync
b26de2ddb274b0e52de6652ad8b45259be2b9913vboxsync/**
bf27591c0d413dd4d7ba41cf89f117171968d462vboxsync * @callback_method_impl{FNDISREADBYTES}
bf27591c0d413dd4d7ba41cf89f117171968d462vboxsync */
bf27591c0d413dd4d7ba41cf89f117171968d462vboxsyncstatic DECLCALLBACK(int) DisasmTest1ReadCode(PDISCPUSTATE pDisState, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead)
bf27591c0d413dd4d7ba41cf89f117171968d462vboxsync{
bf27591c0d413dd4d7ba41cf89f117171968d462vboxsync NOREF(pDisState);
bf27591c0d413dd4d7ba41cf89f117171968d462vboxsync while (cbToRead > 0)
bf27591c0d413dd4d7ba41cf89f117171968d462vboxsync {
bf27591c0d413dd4d7ba41cf89f117171968d462vboxsync *pbDst = g_ab32BitCode[uSrcAddr];
bf27591c0d413dd4d7ba41cf89f117171968d462vboxsync
bf27591c0d413dd4d7ba41cf89f117171968d462vboxsync /* next */
bf27591c0d413dd4d7ba41cf89f117171968d462vboxsync pbDst++;
bf27591c0d413dd4d7ba41cf89f117171968d462vboxsync uSrcAddr++;
bf27591c0d413dd4d7ba41cf89f117171968d462vboxsync cbToRead--;
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync }
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync return 0;
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync}
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync/*
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync * Use an inline function here just to test '__textcoal_nt' sections on darwin.
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync */
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsyncinline int MyDisasm(uintptr_t CodeIndex, PDISCPUSTATE pCpu, uint32_t *pcb)
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync{
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync uint32_t cb;
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync int rc = DISCoreOneEx(CodeIndex, CPUMODE_32BIT, DisasmTest1ReadCode, 0, pCpu, &cb);
bf27591c0d413dd4d7ba41cf89f117171968d462vboxsync *pcb = cb;
bf27591c0d413dd4d7ba41cf89f117171968d462vboxsync MY_PRINTF(("DISCoreOneEx -> rc=%d cb=%d Cpu: opcode=%#x pCurInstr=%p (42=%d)\n", \
bf27591c0d413dd4d7ba41cf89f117171968d462vboxsync rc, cb, pCpu->opcode, pCpu->pCurInstr, 42)); \
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync return rc;
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync}
3e88c818fff5c64b5eff43d5daf4596bd87230c5vboxsync
3e88c818fff5c64b5eff43d5daf4596bd87230c5vboxsync
3e88c818fff5c64b5eff43d5daf4596bd87230c5vboxsyncextern "C" DECLEXPORT(int) DisasmTest1(void)
3e88c818fff5c64b5eff43d5daf4596bd87230c5vboxsync{
3e88c818fff5c64b5eff43d5daf4596bd87230c5vboxsync DISCPUSTATE Cpu;
3e88c818fff5c64b5eff43d5daf4596bd87230c5vboxsync uintptr_t CodeIndex = 0;
3e88c818fff5c64b5eff43d5daf4596bd87230c5vboxsync uint32_t cb;
3e88c818fff5c64b5eff43d5daf4596bd87230c5vboxsync int rc;
3e88c818fff5c64b5eff43d5daf4596bd87230c5vboxsync MY_PRINTF(("DisasmTest1: %p\n", &DisasmTest1));
3e88c818fff5c64b5eff43d5daf4596bd87230c5vboxsync
3e88c818fff5c64b5eff43d5daf4596bd87230c5vboxsync memset(&Cpu, 0, sizeof(Cpu));
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync Cpu.mode = CPUMODE_32BIT;
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync#define DISAS_AND_CHECK(cbInstr, enmOp) \
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync do { \
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync rc = MyDisasm(CodeIndex, &Cpu, &cb); \
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync if (RT_FAILURE(rc)) \
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync return CodeIndex | 0xf000; \
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync if (Cpu.pCurInstr->opcode != (enmOp)) \
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync return CodeIndex| 0xe000; \
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync if (cb != (cbInstr)) \
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync return CodeIndex | 0xd000; \
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync CodeIndex += cb; \
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync } while (0)
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync DISAS_AND_CHECK(1, OP_PUSH);
cab115cfa31c584def7069312a1e23c3fc88533bvboxsync DISAS_AND_CHECK(2, OP_MOV);
cab115cfa31c584def7069312a1e23c3fc88533bvboxsync DISAS_AND_CHECK(3, OP_MOV);
cab115cfa31c584def7069312a1e23c3fc88533bvboxsync DISAS_AND_CHECK(6, OP_CMP);
cab115cfa31c584def7069312a1e23c3fc88533bvboxsync DISAS_AND_CHECK(2, OP_JNE);
cab115cfa31c584def7069312a1e23c3fc88533bvboxsync DISAS_AND_CHECK(3, OP_MOV);
b26de2ddb274b0e52de6652ad8b45259be2b9913vboxsync DISAS_AND_CHECK(4, OP_CMP);
b26de2ddb274b0e52de6652ad8b45259be2b9913vboxsync DISAS_AND_CHECK(2, OP_JNE);
b26de2ddb274b0e52de6652ad8b45259be2b9913vboxsync DISAS_AND_CHECK(5, OP_MOV);
b26de2ddb274b0e52de6652ad8b45259be2b9913vboxsync DISAS_AND_CHECK(2, OP_JMP);
b26de2ddb274b0e52de6652ad8b45259be2b9913vboxsync DISAS_AND_CHECK(2, OP_XOR);
b26de2ddb274b0e52de6652ad8b45259be2b9913vboxsync DISAS_AND_CHECK(2, OP_JNE);
b26de2ddb274b0e52de6652ad8b45259be2b9913vboxsync DISAS_AND_CHECK(3, OP_MOV);
b26de2ddb274b0e52de6652ad8b45259be2b9913vboxsync DISAS_AND_CHECK(1, OP_PUSH);
b26de2ddb274b0e52de6652ad8b45259be2b9913vboxsync DISAS_AND_CHECK(3, OP_MOV);
b26de2ddb274b0e52de6652ad8b45259be2b9913vboxsync DISAS_AND_CHECK(3, OP_MOV);
b26de2ddb274b0e52de6652ad8b45259be2b9913vboxsync DISAS_AND_CHECK(3, OP_CALL);
3e88c818fff5c64b5eff43d5daf4596bd87230c5vboxsync DISAS_AND_CHECK(3, OP_ADD);
3e88c818fff5c64b5eff43d5daf4596bd87230c5vboxsync DISAS_AND_CHECK(1, OP_POP);
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync DISAS_AND_CHECK(1, OP_RETN);
fb7b8c126ea3bc0adf9dd2b2b6a43870ee41853avboxsync DISAS_AND_CHECK(1, OP_INT3);
3e88c818fff5c64b5eff43d5daf4596bd87230c5vboxsync
3e88c818fff5c64b5eff43d5daf4596bd87230c5vboxsync return rc;
3e88c818fff5c64b5eff43d5daf4596bd87230c5vboxsync}
3e88c818fff5c64b5eff43d5daf4596bd87230c5vboxsync
3e88c818fff5c64b5eff43d5daf4596bd87230c5vboxsync