VirtualBox

source: vbox/trunk/src/VBox/VMM/tools/VBoxVMMPreload.cpp@ 94617

Last change on this file since 94617 was 93115, checked in by vboxsync, 3 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.0 KB
Line 
1/* $Id: VBoxVMMPreload.cpp 93115 2022-01-01 11:31:46Z vboxsync $ */
2/** @file
3 * VBoxVMMPreload - Preload VBox the ring-0 modules.
4 */
5
6/*
7 * Copyright (C) 2012-2022 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#include <iprt/buildconfig.h>
23#include <iprt/getopt.h>
24#include <iprt/initterm.h>
25#include <iprt/message.h>
26#include <iprt/path.h>
27#include <iprt/stream.h>
28#include <iprt/string.h>
29#include <iprt/thread.h>
30
31#include <VBox/sup.h>
32#include <VBox/version.h>
33
34
35/*********************************************************************************************************************************
36* Global Variables *
37*********************************************************************************************************************************/
38/**
39 * Known modules and their associated data (there are only known modules!).
40 */
41static struct
42{
43 const char *pszName;
44 bool fPreload;
45 void *pvImageBase;
46} g_aModules[] =
47{
48 { "VMMR0.r0", true, NULL },
49 { "VBoxDDR0.r0", true, NULL },
50};
51
52static uint32_t g_cVerbose = 1;
53static bool g_fLockDown = false;
54
55
56/**
57 * Parses the options.
58 *
59 * @returns RTEXITCODE_SUCCESS on success.
60 * @param argc Argument count .
61 * @param argv Argument vector.
62 * @param pfExit Set to @c true if we should exit.
63 */
64static RTEXITCODE ParseOptions(int argc, char **argv, bool *pfExit)
65{
66 /*
67 * Parse arguments.
68 */
69 static const RTGETOPTDEF s_aOptions[] =
70 {
71 { "--only", 'o', RTGETOPT_REQ_STRING },
72 { "--quiet", 'q', RTGETOPT_REQ_NOTHING },
73 { "--lock" , 'l', RTGETOPT_REQ_NOTHING },
74 { "--verbose", 'v', RTGETOPT_REQ_NOTHING },
75 };
76
77 bool fAll = true;
78
79 int ch;
80 RTGETOPTUNION ValueUnion;
81 RTGETOPTSTATE GetState;
82 RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0 /* fFlags */);
83 while ((ch = RTGetOpt(&GetState, &ValueUnion)))
84 {
85 switch(ch)
86 {
87 case 'o':
88 {
89 uint32_t i;
90
91 if (fAll)
92 {
93 fAll = false;
94 for (i = 0; i < RT_ELEMENTS(g_aModules); i++)
95 g_aModules[i].fPreload = false;
96 }
97
98 i = RT_ELEMENTS(g_aModules);
99 while (i-- > 0)
100 if (!strcmp(ValueUnion.psz, g_aModules[i].pszName))
101 {
102 g_aModules[i].fPreload = true;
103 break;
104 }
105 if (i > RT_ELEMENTS(g_aModules))
106 return RTMsgErrorExit(RTEXITCODE_FAILURE, "No known module '%s'", ValueUnion.psz);
107 break;
108 }
109
110 case 'v':
111 g_cVerbose++;
112 break;
113
114 case 'q':
115 g_cVerbose = 0;
116 break;
117
118 case 'l':
119 g_fLockDown = true;
120 break;
121
122 case 'h':
123 RTPrintf(VBOX_PRODUCT " VMM ring-0 Module Preloader Version " VBOX_VERSION_STRING
124 "(C) 2005-" VBOX_C_YEAR " " VBOX_VENDOR "\n"
125 "All rights reserved.\n"
126 "\n"
127 "Usage: VBoxVMMPreload [-hlqvV] [-o|--only <mod>]\n"
128 "\n");
129 *pfExit = true;
130 return RTEXITCODE_SUCCESS;
131
132 case 'V':
133 RTPrintf("%sr%s\n", RTBldCfgVersion(), RTBldCfgRevisionStr());
134 *pfExit = true;
135 return RTEXITCODE_SUCCESS;
136
137 default:
138 return RTGetOptPrintError(ch, &ValueUnion);
139 }
140 }
141 return RTEXITCODE_SUCCESS;
142}
143
144
145/**
146 * Loads the modules.
147 *
148 * @returns RTEXITCODE_SUCCESS on success.
149 */
150static RTEXITCODE LoadModules(void)
151{
152 RTERRINFOSTATIC ErrInfo;
153
154 for (uint32_t i = 0; i < RT_ELEMENTS(g_aModules); i++)
155 {
156 if (g_aModules[i].fPreload)
157 {
158 char szPath[RTPATH_MAX];
159 int rc = RTPathAppPrivateArch(szPath, sizeof(szPath));
160 if (RT_SUCCESS(rc))
161 rc = RTPathAppend(szPath, sizeof(szPath), g_aModules[i].pszName);
162 if (RT_FAILURE(rc))
163 return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPathAppPrivateArch or RTPathAppend returned %Rrc", rc);
164
165 RTErrInfoInitStatic(&ErrInfo);
166 rc = SUPR3LoadModule(szPath, g_aModules[i].pszName, &g_aModules[i].pvImageBase, &ErrInfo.Core);
167 if (RT_FAILURE(rc))
168 return RTMsgErrorExit(RTEXITCODE_FAILURE, "SUPR3LoadModule failed for %s (%s): %s (rc=%Rrc)",
169 g_aModules[i].pszName, szPath, ErrInfo.Core.pszMsg, rc);
170 if (g_cVerbose >= 1)
171 RTMsgInfo("Loaded '%s' ('%s') at %p\n", szPath, g_aModules[i].pszName, g_aModules[i].pvImageBase);
172 }
173 }
174
175 if (g_fLockDown)
176 {
177 RTErrInfoInitStatic(&ErrInfo);
178 int rc = SUPR3LockDownLoader(&ErrInfo.Core);
179 if (RT_FAILURE(rc))
180 return RTMsgErrorExit(RTEXITCODE_FAILURE, "SUPR3LockDownLoader failed: %s (rc=%Rrc)",
181 ErrInfo.Core.pszMsg, rc);
182 if (g_cVerbose >= 1)
183 RTMsgInfo("Locked down module loader interface!\n");
184 }
185
186 RTStrmFlush(g_pStdOut);
187 return RTEXITCODE_SUCCESS;
188}
189
190
191/**
192 * Entry point.
193 */
194extern "C" DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp)
195{
196 RT_NOREF1(envp);
197 bool fExit = false;
198 RTEXITCODE rcExit = ParseOptions(argc, argv, &fExit);
199 if (rcExit == RTEXITCODE_SUCCESS && !fExit)
200 {
201 rcExit = LoadModules();
202 if (rcExit == RTEXITCODE_SUCCESS)
203 {
204 for (;;)
205 RTThreadSleep(RT_INDEFINITE_WAIT);
206 }
207 }
208 return rcExit;
209}
210
211
212#ifndef VBOX_WITH_HARDENING
213/**
214 * Main entry point.
215 */
216int main(int argc, char **argv, char **envp)
217{
218 int rc = RTR3InitExe(argc, &argv, RTR3INIT_FLAGS_SUPLIB);
219 if (RT_SUCCESS(rc))
220 return TrustedMain(argc, argv, envp);
221 return RTMsgInitFailure(rc);
222}
223#endif /* !VBOX_WITH_HARDENING */
224
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