VirtualBox

source: vbox/trunk/src/VBox/Runtime/tools/RTLdrFlt.cpp@ 34507

Last change on this file since 34507 was 34464, checked in by vboxsync, 14 years ago

IPRT: Added a RTManifest tool for testing the new manifest code. Moved the tools out of testcase/ and into tools/.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.0 KB
Line 
1/* $Id: RTLdrFlt.cpp 34464 2010-11-29 13:45:37Z vboxsync $ */
2/** @file
3 * IPRT - Utility for translating addresses into symbols+offset.
4 */
5
6/*
7 * Copyright (C) 2006-2010 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 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*******************************************************************************
29* Header Files *
30*******************************************************************************/
31#include <iprt/mem.h>
32#include <iprt/assert.h>
33#include <iprt/ctype.h>
34#include <iprt/dbg.h>
35#include <iprt/err.h>
36#include <iprt/getopt.h>
37#include <iprt/initterm.h>
38#include <iprt/message.h>
39#include <iprt/stream.h>
40#include <iprt/string.h>
41
42
43
44/**
45 * Tries to parse out an address at the head of the string.
46 *
47 * @returns true if found address, false if not.
48 * @param psz Where to start parsing.
49 * @param pcchAddress Where to store the address length.
50 * @param pu64Address Where to store the address value.
51 */
52static bool TryParseAddress(const char *psz, size_t *pcchAddress, uint64_t *pu64Address)
53{
54 const char *pszStart = psz;
55
56 /*
57 * Hex prefix?
58 */
59 if (psz[0] == '0' && (psz[1] == 'x' || psz[1] == 'X'))
60 psz += 2;
61
62 /*
63 * How many hex digits? We want at least 4 and at most 16.
64 */
65 size_t off = 0;
66 while (RT_C_IS_XDIGIT(psz[off]))
67 off++;
68 if (off < 4 || off > 16)
69 return false;
70
71 /*
72 * Check for separator (xxxxxxxx'yyyyyyyy).
73 */
74 bool fHave64bitSep = off <= 8
75 && psz[off] == '\''
76 && RT_C_IS_XDIGIT(psz[off + 1])
77 && RT_C_IS_XDIGIT(psz[off + 2])
78 && RT_C_IS_XDIGIT(psz[off + 3])
79 && RT_C_IS_XDIGIT(psz[off + 4])
80 && RT_C_IS_XDIGIT(psz[off + 5])
81 && RT_C_IS_XDIGIT(psz[off + 6])
82 && RT_C_IS_XDIGIT(psz[off + 7])
83 && RT_C_IS_XDIGIT(psz[off + 8])
84 && !RT_C_IS_XDIGIT(psz[off + 9]);
85 if (fHave64bitSep)
86 {
87 uint32_t u32High;
88 int rc = RTStrToUInt32Ex(psz, NULL, 16, &u32High);
89 if (rc != VWRN_TRAILING_CHARS)
90 return false;
91
92 uint32_t u32Low;
93 rc = RTStrToUInt32Ex(&psz[off + 1], NULL, 16, &u32Low);
94 if ( rc != VINF_SUCCESS
95 && rc != VWRN_TRAILING_SPACES
96 && rc != VWRN_TRAILING_CHARS)
97 return false;
98
99 *pu64Address = RT_MAKE_U64(u32Low, u32High);
100 off += 1 + 8;
101 }
102 else
103 {
104 int rc = RTStrToUInt64Ex(psz, NULL, 16, pu64Address);
105 if ( rc != VINF_SUCCESS
106 && rc != VWRN_TRAILING_SPACES
107 && rc != VWRN_TRAILING_CHARS)
108 return false;
109 }
110
111 *pcchAddress = psz + off - pszStart;
112 return true;
113}
114
115
116int main(int argc, char **argv)
117{
118 int rc = RTR3Init();
119 if (RT_FAILURE(rc))
120 return RTMsgInitFailure(rc);
121
122 /*
123 * Create an empty address space that we can load modules and stuff into
124 * as we parse the parameters.
125 */
126 RTDBGAS hAs;
127 rc = RTDbgAsCreate(&hAs, 0, RTUINTPTR_MAX, "");
128 if (RT_FAILURE(rc))
129 return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTDBgAsCreate -> %Rrc\n", rc);
130
131
132 /*
133 * Parse arguments.
134 */
135 static const RTGETOPTDEF s_aOptions[] =
136 {
137 { "--later", 'l', RTGETOPT_REQ_STRING },
138 };
139
140 RTGETOPTUNION ValueUnion;
141 RTGETOPTSTATE GetState;
142 RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0);
143 while ((rc = RTGetOpt(&GetState, &ValueUnion)))
144 {
145 switch (rc)
146 {
147 case 'h':
148 RTPrintf("help: todo\n");
149 break;
150
151 case 'V':
152 RTPrintf("$Revision: 34464 $");
153 return RTEXITCODE_SUCCESS;
154
155 case VINF_GETOPT_NOT_OPTION:
156 {
157 /* <address> <module> */
158 rc = RTGetOptFetchValue(&GetState, &ValueUnion, RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_HEX);
159 if (RT_FAILURE(rc))
160 return RTGetOptPrintError(rc, &ValueUnion);
161 uint64_t u64Address = ValueUnion.u64;
162
163 rc = RTGetOptFetchValue(&GetState, &ValueUnion, RTGETOPT_REQ_STRING);
164 if (RT_FAILURE(rc))
165 return RTGetOptPrintError(rc, &ValueUnion);
166 const char *pszModule = ValueUnion.psz;
167
168 RTDBGMOD hMod;
169 rc = RTDbgModCreateFromImage(&hMod, pszModule, NULL, 0 /*fFlags*/);
170 if (RT_FAILURE(rc))
171 return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTDbgModCreateFromImage(,%s,,) -> %Rrc\n", pszModule, rc);
172
173 rc = RTDbgAsModuleLink(hAs, hMod, u64Address, 0 /* fFlags */);
174 if (RT_FAILURE(rc))
175 return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTDbgAsModuleLink(,%s,%llx,) -> %Rrc\n", pszModule, u64Address, rc);
176 break;
177 }
178
179 default:
180 return RTGetOptPrintError(rc, &ValueUnion);
181 }
182 }
183
184 /*
185 * Read text from standard input and see if there is anything we can translate.
186 */
187 for (;;)
188 {
189 /* Get a line. */
190 char szLine[_64K];
191 rc = RTStrmGetLine(g_pStdIn, szLine, sizeof(szLine));
192 if (rc == VERR_EOF)
193 break;
194 if (RT_FAILURE(rc))
195 return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTStrmGetLine() -> %Rrc\n", rc);
196
197 /*
198 * Search the line for potential addresses and replace them with
199 * symbols+offset.
200 */
201 const char *pszStart = szLine;
202 const char *psz = szLine;
203 char ch;
204 while ((ch = *psz) != '\0')
205 {
206 size_t cchAddress;
207 uint64_t u64Address;
208
209 if ( ( ch == '0'
210 && (psz[1] == 'x' || psz[1] == 'X')
211 && TryParseAddress(psz, &cchAddress, &u64Address))
212 || ( RT_C_IS_XDIGIT(ch)
213 && TryParseAddress(psz, &cchAddress, &u64Address))
214 )
215 {
216 if (pszStart != psz)
217 RTStrmWrite(g_pStdOut, pszStart, psz - pszStart);
218 pszStart = psz;
219
220 RTDBGSYMBOL Symbol;
221 RTINTPTR off;
222 rc = RTDbgAsSymbolByAddr(hAs, u64Address, &off, &Symbol, NULL);
223 if (RT_SUCCESS(rc))
224 {
225 if (!off)
226 RTStrmPrintf(g_pStdOut, "%.*s=[%s]", cchAddress, psz, Symbol.szName);
227 else if (off > 0)
228 RTStrmPrintf(g_pStdOut, "%.*s=[%s+%#llx]", cchAddress, psz, Symbol.szName, off);
229 else
230 RTStrmPrintf(g_pStdOut, "%.*s=[%s-%#llx]", cchAddress, psz, Symbol.szName, -off);
231 psz += cchAddress;
232 pszStart = psz;
233 }
234 else
235 psz += cchAddress;
236 }
237 else
238 psz++;
239 }
240
241 if (pszStart != psz)
242 RTStrmWrite(g_pStdOut, pszStart, psz - pszStart);
243 RTStrmPutCh(g_pStdOut, '\n');
244
245 }
246
247 return RTEXITCODE_SUCCESS;
248}
249
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