VirtualBox

source: vbox/trunk/src/VBox/VMM/Preload/VBoxVMMPreload.cpp@ 41074

Last change on this file since 41074 was 41074, checked in by vboxsync, 12 years ago

VMM preloader.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.2 KB
Line 
1/* $Id: VBoxVMMPreload.cpp 41074 2012-04-26 23:11:45Z vboxsync $ */
2/** @file
3 * VBoxVMMPreload - Preload VBox the ring-0 modules.
4 */
5
6/*
7 * Copyright (C) 2012 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 bool fVMM;
46 void *pvImageBase;
47} g_aModules[] =
48{
49 { "VMMR0.r0", true, true, NULL },
50 { "VBoxDDR0.r0", false, true, NULL },
51 { "VBoxDD2R0.r0", false, true, NULL },
52};
53
54static uint32_t g_cVerbose = 1;
55
56
57/**
58 * Parses the options.
59 *
60 * @returns RTEXITCODE_SUCCESS on success.
61 * @param argc Argument count .
62 * @param argv Argument vector.
63 * @param pfExit Set to @c true if we should exit.
64 */
65static RTEXITCODE ParseOptions(int argc, char **argv, bool *pfExit)
66{
67 /*
68 * Parse arguments.
69 */
70 static const RTGETOPTDEF s_aOptions[] =
71 {
72 { "--only", 'o', RTGETOPT_REQ_STRING },
73 { "--quiet", 'q', 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 'h':
119 RTPrintf(VBOX_PRODUCT " VMM ring-0 Module Preloader Version " VBOX_VERSION_STRING
120 "(C) 2005-" VBOX_C_YEAR " " VBOX_VENDOR "\n"
121 "All rights reserved.\n"
122 "\n"
123 "Usage: VBoxVMMPreload [-hqvV] [-o|--only <mod>]\n"
124 "\n");
125 *pfExit = true;
126 return RTEXITCODE_SUCCESS;
127
128 case 'V':
129 RTPrintf("%sr%s\n", RTBldCfgVersion(), RTBldCfgRevisionStr());
130 *pfExit = true;
131 return RTEXITCODE_SUCCESS;
132
133 default:
134 return RTGetOptPrintError(ch, &ValueUnion);
135 }
136 }
137 return RTEXITCODE_SUCCESS;
138}
139
140
141/**
142 * Loads the modules.
143 *
144 * @returns RTEXITCODE_SUCCESS on success.
145 */
146static RTEXITCODE LoadModules(void)
147{
148 for (uint32_t i = 0; i < RT_ELEMENTS(g_aModules); i++)
149 {
150 if (g_aModules[i].fPreload)
151 {
152 char szPath[RTPATH_MAX];
153 int rc = RTPathAppPrivateArch(szPath, sizeof(szPath));
154 if (RT_SUCCESS(rc))
155 rc = RTPathAppend(szPath, sizeof(szPath), g_aModules[i].pszName);
156 if (RT_FAILURE(rc))
157 return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPathAppPrivateArch or RTPathAppend returned %Rrc", rc);
158
159 void *pvImageBase;
160 RTERRINFOSTATIC ErrInfo;
161 RTErrInfoInitStatic(&ErrInfo);
162 rc = SUPR3LoadModule(szPath, g_aModules[i].pszName, &g_aModules[i].pvImageBase, &ErrInfo.Core);
163 if (RT_FAILURE(rc))
164 return RTMsgErrorExit(RTEXITCODE_FAILURE, "SUPR3LoadModule failed for %s (%s): %s (rc=%Rrc)",
165 g_aModules[i].pszName, szPath, ErrInfo.Core.pszMsg, rc);
166 if (g_cVerbose > 1)
167 RTMsgInfo("Loaded '%s' ('%s') at %p\n", szPath, g_aModules[i].pszName, g_aModules[i].pvImageBase);
168 }
169 }
170
171 return RTEXITCODE_SUCCESS;
172}
173
174
175/**
176 * Entry point.
177 */
178extern "C" DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp)
179{
180 bool fExit = false;
181 RTEXITCODE rcExit = ParseOptions(argc, argv, &fExit);
182 if (rcExit == RTEXITCODE_SUCCESS && !fExit)
183 {
184 rcExit = LoadModules();
185 if (rcExit == RTEXITCODE_SUCCESS)
186 {
187 for (;;)
188 RTThreadSleep(RT_INDEFINITE_WAIT);
189 }
190 }
191 return rcExit;
192}
193
194
195#ifndef VBOX_WITH_HARDENING
196/**
197 * Main entry point.
198 */
199int main(int argc, char **argv, char **envp)
200{
201 int rc = RTR3InitExe(argc, &argv, RTR3INIT_FLAGS_SUPLIB);
202 if (RT_FAILURE(rc))
203 return RTMsgInitFailure(rc);
204 return TrustedMain(argc, argv, envp);
205}
206#endif /* !VBOX_WITH_HARDENING */
207
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