VirtualBox

source: vbox/trunk/src/VBox/Runtime/testcase/tstLdrDisasmTest.cpp@ 100762

Last change on this file since 100762 was 99775, checked in by vboxsync, 19 months ago

*: Mark functions as static if not used outside of a given compilation unit. Enables the compiler to optimize inlining, reduces the symbol tables, exposes unused functions and in some rare cases exposes mismtaches between function declarations and definitions, but most importantly reduces the number of parfait reports for the extern-function-no-forward-declaration category. This should not result in any functional changes, bugref:3409

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 6.9 KB
Line 
1/* $Id: tstLdrDisasmTest.cpp 99775 2023-05-12 12:21:58Z vboxsync $ */
2/** @file
3 * IPRT - RTLdr test object.
4 *
5 * We use precompiled versions of this object for testing all the loaders.
6 *
7 * This is not supposed to be pretty or usable code, just something which
8 * make life difficult for the loader.
9 */
10
11/*
12 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
13 *
14 * This file is part of VirtualBox base platform packages, as
15 * available from https://www.virtualbox.org.
16 *
17 * This program is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU General Public License
19 * as published by the Free Software Foundation, in version 3 of the
20 * License.
21 *
22 * This program is distributed in the hope that it will be useful, but
23 * WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 * General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, see <https://www.gnu.org/licenses>.
29 *
30 * The contents of this file may alternatively be used under the terms
31 * of the Common Development and Distribution License Version 1.0
32 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
33 * in the VirtualBox distribution, in which case the provisions of the
34 * CDDL are applicable instead of those of the GPL.
35 *
36 * You may elect to license modified versions of this file under the
37 * terms and conditions of either the GPL or the CDDL or both.
38 *
39 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
40 */
41
42
43
44/*********************************************************************************************************************************
45* Header Files *
46*********************************************************************************************************************************/
47#include <VBox/dis.h>
48#include <VBox/sup.h>
49#include <iprt/string.h>
50
51#if defined(IN_RING0)
52# define MY_PRINTF(a) SUPR0Printf a
53#else
54# define MY_PRINTF(a) do {} while (0)
55#endif
56
57
58/*********************************************************************************************************************************
59* Global Variables *
60*********************************************************************************************************************************/
61
62/* 32-bit code */
63static const uint8_t g_ab32BitCode[] =
64{
65 0x55, // 1000ab50 55 push ebp
66 0x8b,0xec, // 1000ab51 8bec mov ebp,esp
67 0x8b,0x45,0x08, // 1000ab53 8b4508 mov eax,dword ptr [ebp+8]
68 0x81,0x38,0x07,0x07,// 1000ab56 813807076419 cmp dword ptr [eax],19640707h
69 0x64,0x19,
70 0x75,0x09, // 1000ab5c 7509 jne kLdr!kLdrModMap+0x17 (1000ab67)
71 0x8b,0x4d,0x08, // 1000ab5e 8b4d08 mov ecx,dword ptr [ebp+8]
72 0x83,0x79,0x2c,0x00,// 1000ab61 83792c00 cmp dword ptr [ecx+2Ch],0
73 0x75,0x07, // 1000ab65 7507 jne kLdr!kLdrModMap+0x1e (1000ab6e)
74 0xb8,0xc0,0x68,0x06,// 1000ab67 b8c0680600 mov eax,668C0h
75 0x00,
76 0xeb,0x14, // 1000ab6c eb14 jmp kLdr!kLdrModMap+0x32 (1000ab82)
77 0x33,0xd2, // 1000ab6e 33d2 xor edx,edx
78 0x75,0xe1, // 1000ab70 75e1 jne kLdr!kLdrModMap+0x3 (1000ab53)
79 0x8b,0x45,0x08, // 1000ab72 8b4508 mov eax,dword ptr [ebp+8]
80 0x50, // 1000ab75 50 push eax
81 0x8b,0x4d,0x08, // 1000ab76 8b4d08 mov ecx,dword ptr [ebp+8]
82 0x8b,0x51,0x2c, // 1000ab79 8b512c mov edx,dword ptr [ecx+2Ch]
83 0xff,0x52,0x3c, // 1000ab7c ff523c call dword ptr [edx+3Ch]
84 0x83,0xc4,0x04, // 1000ab7f 83c404 add esp,4
85 0x5d, // 1000ab82 5d pop ebp
86 0xc3, // 1000ab83 c3 ret
87 0xcc
88};
89
90
91/**
92 * @callback_method_impl{FNDISREADBYTES}
93 */
94static DECLCALLBACK(int) DisasmTest1ReadCode(PDISSTATE pDis, uint8_t offInstr, uint8_t cbMinRead, uint8_t cbMaxRead)
95{
96 size_t cb = cbMaxRead;
97 if (cb + pDis->uInstrAddr + offInstr > sizeof(g_ab32BitCode))
98 cb = cbMinRead;
99 memcpy(&pDis->u.abInstr[offInstr], &g_ab32BitCode[pDis->uInstrAddr + offInstr], cb);
100 pDis->cbCachedInstr = offInstr + (uint8_t)cb;
101 return VINF_SUCCESS;
102}
103
104
105/*
106 * Use an inline function here just to test '__textcoal_nt' sections on darwin.
107 */
108DECLINLINE(int) MyDisasm(uintptr_t CodeIndex, PDISSTATE pDis, uint32_t *pcb)
109{
110 uint32_t cb;
111 int rc = DISInstrWithReader(CodeIndex, DISCPUMODE_32BIT, DisasmTest1ReadCode, 0, pDis, &cb);
112 *pcb = cb;
113 MY_PRINTF(("DISCoreOneEx -> rc=%d cb=%d Cpu: bOpCode=%#x pCurInstr=%p (42=%d)\n", \
114 rc, cb, pDis->arch.x86.bOpCode, pDis->pCurInstr, 42)); \
115 return rc;
116}
117
118
119extern "C" DECLEXPORT(int) DisasmTest1(void)
120{
121 DISSTATE Dis;
122 uintptr_t CodeIndex = 0;
123 uint32_t cb;
124 int rc;
125 MY_PRINTF(("DisasmTest1: %p\n", &DisasmTest1));
126
127#if defined(IN_RING0)
128 MY_PRINTF(("GIP: g_pSUPGlobalInfoPage=%p\n", g_pSUPGlobalInfoPage));
129 MY_PRINTF(("GIP: magic=%#x version=%#x mode=%d cCpus=%d\n", g_pSUPGlobalInfoPage->u32Magic, g_pSUPGlobalInfoPage->u32Version,
130 g_pSUPGlobalInfoPage->u32Mode, g_pSUPGlobalInfoPage->cCpus));
131 if (g_pSUPGlobalInfoPage->u32Magic != SUPGLOBALINFOPAGE_MAGIC)
132 return 0xc001;
133 if (g_pSUPGlobalInfoPage->u32Version != SUPGLOBALINFOPAGE_VERSION)
134 return 0xc002;
135 if (g_pSUPGlobalInfoPage->u32Mode != SUPGIPMODE_INVARIANT_TSC)
136 return 0xc003;
137 if (g_pSUPGlobalInfoPage->cCpus != 42)
138 return 0xc004;
139#endif
140
141 memset(&Dis, 0, sizeof(Dis));
142
143#define DISAS_AND_CHECK(cbInstr, enmOp) \
144 do { \
145 rc = MyDisasm(CodeIndex, &Dis, &cb); \
146 if (RT_FAILURE(rc)) \
147 return CodeIndex | 0xf000; \
148 if (Dis.pCurInstr->uOpcode != (enmOp)) \
149 return CodeIndex| 0xe000; \
150 if (cb != (cbInstr)) \
151 return CodeIndex | 0xd000; \
152 CodeIndex += cb; \
153 } while (0)
154
155 DISAS_AND_CHECK(1, OP_PUSH);
156 DISAS_AND_CHECK(2, OP_MOV);
157 DISAS_AND_CHECK(3, OP_MOV);
158 DISAS_AND_CHECK(6, OP_CMP);
159 DISAS_AND_CHECK(2, OP_JNE);
160 DISAS_AND_CHECK(3, OP_MOV);
161 DISAS_AND_CHECK(4, OP_CMP);
162 DISAS_AND_CHECK(2, OP_JNE);
163 DISAS_AND_CHECK(5, OP_MOV);
164 DISAS_AND_CHECK(2, OP_JMP);
165 DISAS_AND_CHECK(2, OP_XOR);
166 DISAS_AND_CHECK(2, OP_JNE);
167 DISAS_AND_CHECK(3, OP_MOV);
168 DISAS_AND_CHECK(1, OP_PUSH);
169 DISAS_AND_CHECK(3, OP_MOV);
170 DISAS_AND_CHECK(3, OP_MOV);
171 DISAS_AND_CHECK(3, OP_CALL);
172 DISAS_AND_CHECK(3, OP_ADD);
173 DISAS_AND_CHECK(1, OP_POP);
174 DISAS_AND_CHECK(1, OP_RETN);
175 DISAS_AND_CHECK(1, OP_INT3);
176
177 return rc;
178}
179
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette