VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/ldr/ldrEx.cpp@ 51701

Last change on this file since 51701 was 49044, checked in by vboxsync, 11 years ago

Darwin guest OS digger hacking in progress. Adding symbol cache util to iprt and started on the Mach-O code that'll make use of it (RTDbgModCreateFromMachOImage++). Updates kStuff from 53 to 55 for UUID query and 64-bit kext loading.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 21.4 KB
Line 
1/* $Id: ldrEx.cpp 49044 2013-10-11 01:06:28Z vboxsync $ */
2/** @file
3 * IPRT - Binary Image Loader, Extended Features.
4 */
5
6/*
7 * Copyright (C) 2006-2013 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#define LOG_GROUP RTLOGGROUP_LDR
32#include <iprt/ldr.h>
33#include "internal/iprt.h"
34
35#include <iprt/alloc.h>
36#include <iprt/assert.h>
37#include <iprt/log.h>
38#include <iprt/string.h>
39#include <iprt/err.h>
40#include "internal/ldr.h"
41#include "internal/ldrMZ.h"
42
43
44/**
45 * Open part with reader.
46 *
47 * @returns iprt status code.
48 * @param pReader The loader reader instance which will provide the raw image bits.
49 * @param fFlags Reserved, MBZ.
50 * @param enmArch Architecture specifier.
51 * @param phMod Where to store the handle.
52 */
53int rtldrOpenWithReader(PRTLDRREADER pReader, uint32_t fFlags, RTLDRARCH enmArch, PRTLDRMOD phMod)
54{
55 /*
56 * Read and verify the file signature.
57 */
58 union
59 {
60 char ach[4];
61 uint16_t au16[2];
62 uint32_t u32;
63 } uSign;
64 int rc = pReader->pfnRead(pReader, &uSign, sizeof(uSign), 0);
65 if (RT_FAILURE(rc))
66 return rc;
67#ifndef LDR_WITH_KLDR
68 if ( uSign.au16[0] != IMAGE_DOS_SIGNATURE
69 && uSign.u32 != IMAGE_NT_SIGNATURE
70 && uSign.u32 != IMAGE_ELF_SIGNATURE
71 && uSign.au16[0] != IMAGE_LX_SIGNATURE)
72 {
73 Log(("rtldrOpenWithReader: %s: unknown magic %#x / '%.4s\n", pReader->pfnLogName(pReader), uSign.u32, &uSign.ach[0]));
74 return VERR_INVALID_EXE_SIGNATURE;
75 }
76#endif
77 uint32_t offHdr = 0;
78 if (uSign.au16[0] == IMAGE_DOS_SIGNATURE)
79 {
80 rc = pReader->pfnRead(pReader, &offHdr, sizeof(offHdr), RT_OFFSETOF(IMAGE_DOS_HEADER, e_lfanew));
81 if (RT_FAILURE(rc))
82 return rc;
83
84 if (offHdr <= sizeof(IMAGE_DOS_HEADER))
85 {
86 Log(("rtldrOpenWithReader: %s: no new header / invalid offset %#RX32\n", pReader->pfnLogName(pReader), offHdr));
87 return VERR_INVALID_EXE_SIGNATURE;
88 }
89 rc = pReader->pfnRead(pReader, &uSign, sizeof(uSign), offHdr);
90 if (RT_FAILURE(rc))
91 return rc;
92 if ( uSign.u32 != IMAGE_NT_SIGNATURE
93 && uSign.au16[0] != IMAGE_LX_SIGNATURE
94 && uSign.au16[0] != IMAGE_LE_SIGNATURE
95 && uSign.au16[0] != IMAGE_NE_SIGNATURE)
96 {
97 Log(("rtldrOpenWithReader: %s: unknown new magic %#x / '%.4s\n", pReader->pfnLogName(pReader), uSign.u32, &uSign.ach[0]));
98 return VERR_INVALID_EXE_SIGNATURE;
99 }
100 }
101
102 /*
103 * Create image interpreter instance depending on the signature.
104 */
105 if (uSign.u32 == IMAGE_NT_SIGNATURE)
106#ifdef LDR_WITH_PE
107 rc = rtldrPEOpen(pReader, fFlags, enmArch, offHdr, phMod);
108#else
109 rc = VERR_PE_EXE_NOT_SUPPORTED;
110#endif
111 else if (uSign.u32 == IMAGE_ELF_SIGNATURE)
112#if defined(LDR_WITH_ELF)
113 rc = rtldrELFOpen(pReader, fFlags, enmArch, phMod);
114#else
115 rc = VERR_ELF_EXE_NOT_SUPPORTED;
116#endif
117 else if (uSign.au16[0] == IMAGE_LX_SIGNATURE)
118#ifdef LDR_WITH_LX
119 rc = rtldrLXOpen(pReader, fFlags, enmArch, offHdr, phMod);
120#else
121 rc = VERR_LX_EXE_NOT_SUPPORTED;
122#endif
123 else if (uSign.au16[0] == IMAGE_LE_SIGNATURE)
124#ifdef LDR_WITH_LE
125 rc = rtldrLEOpen(pReader, fFlags, enmArch, phMod);
126#else
127 rc = VERR_LE_EXE_NOT_SUPPORTED;
128#endif
129 else if (uSign.au16[0] == IMAGE_NE_SIGNATURE)
130#ifdef LDR_WITH_NE
131 rc = rtldrNEOpen(pReader, fFlags, enmArch, phMod);
132#else
133 rc = VERR_NE_EXE_NOT_SUPPORTED;
134#endif
135 else if (uSign.au16[0] == IMAGE_DOS_SIGNATURE)
136#ifdef LDR_WITH_MZ
137 rc = rtldrMZOpen(pReader, fFlags, enmArch, phMod);
138#else
139 rc = VERR_MZ_EXE_NOT_SUPPORTED;
140#endif
141 else if (/* uSign.u32 == IMAGE_AOUT_A_SIGNATURE
142 || uSign.u32 == IMAGE_AOUT_Z_SIGNATURE*/ /** @todo find the aout magics in emx or binutils. */
143 0)
144#ifdef LDR_WITH_AOUT
145 rc = rtldrAOUTOpen(pReader, fFlags, enmArch, phMod);
146#else
147 rc = VERR_AOUT_EXE_NOT_SUPPORTED;
148#endif
149 else
150 {
151#ifndef LDR_WITH_KLDR
152 Log(("rtldrOpenWithReader: %s: the format isn't implemented %#x / '%.4s\n", pReader->pfnLogName(pReader), uSign.u32, &uSign.ach[0]));
153#endif
154 rc = VERR_INVALID_EXE_SIGNATURE;
155 }
156
157#ifdef LDR_WITH_KLDR
158 /* Try kLdr if it's a format we don't recognize. */
159 if (rc <= VERR_INVALID_EXE_SIGNATURE && rc > VERR_BAD_EXE_FORMAT)
160 rc = rtldrkLdrOpen(pReader, fFlags, enmArch, phMod);
161#endif
162
163 LogFlow(("rtldrOpenWithReader: %s: returns %Rrc *phMod=%p\n", pReader->pfnLogName(pReader), rc, *phMod));
164 return rc;
165}
166
167
168RTDECL(size_t) RTLdrSize(RTLDRMOD hLdrMod)
169{
170 LogFlow(("RTLdrSize: hLdrMod=%RTldrm\n", hLdrMod));
171
172 /*
173 * Validate input.
174 */
175 AssertMsgReturn(rtldrIsValid(hLdrMod), ("hLdrMod=%p\n", hLdrMod), ~(size_t)0);
176 PRTLDRMODINTERNAL pMod = (PRTLDRMODINTERNAL)hLdrMod;
177 AssertMsgReturn(pMod->eState == LDR_STATE_OPENED, ("eState=%d\n", pMod->eState), ~(size_t)0);
178
179 /*
180 * Do it.
181 */
182 size_t cb = pMod->pOps->pfnGetImageSize(pMod);
183 LogFlow(("RTLdrSize: returns %zu\n", cb));
184 return cb;
185}
186RT_EXPORT_SYMBOL(RTLdrSize);
187
188
189/**
190 * Loads the image into a buffer provided by the user and applies fixups
191 * for the given base address.
192 *
193 * @returns iprt status code.
194 * @param hLdrMod The load module handle.
195 * @param pvBits Where to put the bits.
196 * Must be as large as RTLdrSize() suggests.
197 * @param BaseAddress The base address.
198 * @param pfnGetImport Callback function for resolving imports one by one.
199 * @param pvUser User argument for the callback.
200 * @remark Not supported for RTLdrLoad() images.
201 */
202RTDECL(int) RTLdrGetBits(RTLDRMOD hLdrMod, void *pvBits, RTLDRADDR BaseAddress, PFNRTLDRIMPORT pfnGetImport, void *pvUser)
203{
204 LogFlow(("RTLdrGetBits: hLdrMod=%RTldrm pvBits=%p BaseAddress=%RTptr pfnGetImport=%p pvUser=%p\n",
205 hLdrMod, pvBits, BaseAddress, pfnGetImport, pvUser));
206
207 /*
208 * Validate input.
209 */
210 AssertMsgReturn(rtldrIsValid(hLdrMod), ("hLdrMod=%p\n", hLdrMod), VERR_INVALID_HANDLE);
211 AssertMsgReturn(VALID_PTR(pvBits), ("pvBits=%p\n", pvBits), VERR_INVALID_PARAMETER);
212 AssertMsgReturn(VALID_PTR(pfnGetImport), ("pfnGetImport=%p\n", pfnGetImport), VERR_INVALID_PARAMETER);
213 PRTLDRMODINTERNAL pMod = (PRTLDRMODINTERNAL)hLdrMod;
214 AssertMsgReturn(pMod->eState == LDR_STATE_OPENED, ("eState=%d\n", pMod->eState), VERR_WRONG_ORDER);
215
216 /*
217 * Do it.
218 */
219 int rc = pMod->pOps->pfnGetBits(pMod, pvBits, BaseAddress, pfnGetImport, pvUser);
220 LogFlow(("RTLdrGetBits: returns %Rrc\n",rc));
221 return rc;
222}
223RT_EXPORT_SYMBOL(RTLdrGetBits);
224
225
226/**
227 * Relocates bits after getting them.
228 * Useful for code which moves around a bit.
229 *
230 * @returns iprt status code.
231 * @param hLdrMod The loader module handle.
232 * @param pvBits Where the image bits are.
233 * Must have been passed to RTLdrGetBits().
234 * @param NewBaseAddress The new base address.
235 * @param OldBaseAddress The old base address.
236 * @param pfnGetImport Callback function for resolving imports one by one.
237 * @param pvUser User argument for the callback.
238 * @remark Not supported for RTLdrLoad() images.
239 */
240RTDECL(int) RTLdrRelocate(RTLDRMOD hLdrMod, void *pvBits, RTLDRADDR NewBaseAddress, RTLDRADDR OldBaseAddress,
241 PFNRTLDRIMPORT pfnGetImport, void *pvUser)
242{
243 LogFlow(("RTLdrRelocate: hLdrMod=%RTldrm pvBits=%p NewBaseAddress=%RTptr OldBaseAddress=%RTptr pfnGetImport=%p pvUser=%p\n",
244 hLdrMod, pvBits, NewBaseAddress, OldBaseAddress, pfnGetImport, pvUser));
245
246 /*
247 * Validate input.
248 */
249 AssertMsgReturn(rtldrIsValid(hLdrMod), ("hLdrMod=%p\n", hLdrMod), VERR_INVALID_HANDLE);
250 AssertMsgReturn(VALID_PTR(pvBits), ("pvBits=%p\n", pvBits), VERR_INVALID_PARAMETER);
251 AssertMsgReturn(VALID_PTR(pfnGetImport), ("pfnGetImport=%p\n", pfnGetImport), VERR_INVALID_PARAMETER);
252 PRTLDRMODINTERNAL pMod = (PRTLDRMODINTERNAL)hLdrMod;
253 AssertMsgReturn(pMod->eState == LDR_STATE_OPENED, ("eState=%d\n", pMod->eState), VERR_WRONG_ORDER);
254
255 /*
256 * Do it.
257 */
258 int rc = pMod->pOps->pfnRelocate(pMod, pvBits, NewBaseAddress, OldBaseAddress, pfnGetImport, pvUser);
259 LogFlow(("RTLdrRelocate: returns %Rrc\n", rc));
260 return rc;
261}
262RT_EXPORT_SYMBOL(RTLdrRelocate);
263
264
265/**
266 * Gets the address of a named exported symbol.
267 *
268 * This function differs from the plain one in that it can deal with
269 * both GC and HC address sizes, and that it can calculate the symbol
270 * value relative to any given base address.
271 *
272 * @returns iprt status code.
273 * @param hLdrMod The loader module handle.
274 * @param pvBits Optional pointer to the loaded image.
275 * Set this to NULL if no RTLdrGetBits() processed image bits are available.
276 * Not supported for RTLdrLoad() images and must be NULL.
277 * @param BaseAddress Image load address.
278 * Not supported for RTLdrLoad() images and must be 0.
279 * @param pszSymbol Symbol name.
280 * @param pValue Where to store the symbol value.
281 */
282RTDECL(int) RTLdrGetSymbolEx(RTLDRMOD hLdrMod, const void *pvBits, RTLDRADDR BaseAddress, const char *pszSymbol,
283 PRTLDRADDR pValue)
284{
285 LogFlow(("RTLdrGetSymbolEx: hLdrMod=%RTldrm pvBits=%p BaseAddress=%RTptr pszSymbol=%p:{%s} pValue\n",
286 hLdrMod, pvBits, BaseAddress, pszSymbol, pszSymbol, pValue));
287
288 /*
289 * Validate input.
290 */
291 AssertMsgReturn(rtldrIsValid(hLdrMod), ("hLdrMod=%p\n", hLdrMod), VERR_INVALID_HANDLE);
292 AssertMsgReturn(!pvBits || VALID_PTR(pvBits), ("pvBits=%p\n", pvBits), VERR_INVALID_PARAMETER);
293 AssertMsgReturn(pszSymbol, ("pszSymbol=%p\n", pszSymbol), VERR_INVALID_PARAMETER);
294 AssertMsgReturn(VALID_PTR(pValue), ("pValue=%p\n", pvBits), VERR_INVALID_PARAMETER);
295 PRTLDRMODINTERNAL pMod = (PRTLDRMODINTERNAL)hLdrMod;
296 //AssertMsgReturn(pMod->eState == LDR_STATE_OPENED, ("eState=%d\n", pMod->eState), VERR_WRONG_ORDER);
297
298 /*
299 * Do it.
300 */
301 int rc;
302 if (pMod->pOps->pfnGetSymbolEx)
303 rc = pMod->pOps->pfnGetSymbolEx(pMod, pvBits, BaseAddress, pszSymbol, pValue);
304 else if (!BaseAddress && !pvBits)
305 {
306 void *pvValue;
307 rc = pMod->pOps->pfnGetSymbol(pMod, pszSymbol, &pvValue);
308 if (RT_SUCCESS(rc))
309 *pValue = (uintptr_t)pvValue;
310 }
311 else
312 AssertMsgFailedReturn(("BaseAddress=%RTptr pvBits=%p\n", BaseAddress, pvBits), VERR_INVALID_FUNCTION);
313 LogFlow(("RTLdrGetSymbolEx: returns %Rrc *pValue=%p\n", rc, *pValue));
314 return rc;
315}
316RT_EXPORT_SYMBOL(RTLdrGetSymbolEx);
317
318
319/**
320 * Enumerates all symbols in a module.
321 *
322 * @returns iprt status code.
323 * @param hLdrMod The loader module handle.
324 * @param fFlags Flags indicating what to return and such.
325 * @param pvBits Optional pointer to the loaded image.
326 * Set this to NULL if no RTLdrGetBits() processed image bits are available.
327 * @param BaseAddress Image load address.
328 * @param pfnCallback Callback function.
329 * @param pvUser User argument for the callback.
330 * @remark Not supported for RTLdrLoad() images.
331 */
332RTDECL(int) RTLdrEnumSymbols(RTLDRMOD hLdrMod, unsigned fFlags, const void *pvBits, RTLDRADDR BaseAddress,
333 PFNRTLDRENUMSYMS pfnCallback, void *pvUser)
334{
335 LogFlow(("RTLdrEnumSymbols: hLdrMod=%RTldrm fFlags=%#x pvBits=%p BaseAddress=%RTptr pfnCallback=%p pvUser=%p\n",
336 hLdrMod, fFlags, pvBits, BaseAddress, pfnCallback, pvUser));
337
338 /*
339 * Validate input.
340 */
341 AssertMsgReturn(rtldrIsValid(hLdrMod), ("hLdrMod=%p\n", hLdrMod), VERR_INVALID_HANDLE);
342 AssertMsgReturn(!pvBits || VALID_PTR(pvBits), ("pvBits=%p\n", pvBits), VERR_INVALID_PARAMETER);
343 AssertMsgReturn(VALID_PTR(pfnCallback), ("pfnCallback=%p\n", pfnCallback), VERR_INVALID_PARAMETER);
344 PRTLDRMODINTERNAL pMod = (PRTLDRMODINTERNAL)hLdrMod;
345 //AssertMsgReturn(pMod->eState == LDR_STATE_OPENED, ("eState=%d\n", pMod->eState), VERR_WRONG_ORDER);
346
347 /*
348 * Do it.
349 */
350 int rc = pMod->pOps->pfnEnumSymbols(pMod, fFlags, pvBits, BaseAddress, pfnCallback, pvUser);
351 LogFlow(("RTLdrEnumSymbols: returns %Rrc\n", rc));
352 return rc;
353}
354RT_EXPORT_SYMBOL(RTLdrEnumSymbols);
355
356
357RTDECL(int) RTLdrEnumDbgInfo(RTLDRMOD hLdrMod, const void *pvBits, PFNRTLDRENUMDBG pfnCallback, void *pvUser)
358{
359 LogFlow(("RTLdrEnumDbgInfo: hLdrMod=%RTldrm pvBits=%p pfnCallback=%p pvUser=%p\n",
360 hLdrMod, pvBits, pfnCallback, pvUser));
361
362 /*
363 * Validate input.
364 */
365 AssertMsgReturn(rtldrIsValid(hLdrMod), ("hLdrMod=%p\n", hLdrMod), VERR_INVALID_HANDLE);
366 AssertMsgReturn(!pvBits || RT_VALID_PTR(pvBits), ("pvBits=%p\n", pvBits), VERR_INVALID_PARAMETER);
367 AssertMsgReturn(RT_VALID_PTR(pfnCallback), ("pfnCallback=%p\n", pfnCallback), VERR_INVALID_PARAMETER);
368 PRTLDRMODINTERNAL pMod = (PRTLDRMODINTERNAL)hLdrMod;
369 //AssertMsgReturn(pMod->eState == LDR_STATE_OPENED, ("eState=%d\n", pMod->eState), VERR_WRONG_ORDER);
370
371 /*
372 * Do it.
373 */
374 int rc;
375 if (pMod->pOps->pfnEnumDbgInfo)
376 rc = pMod->pOps->pfnEnumDbgInfo(pMod, pvBits, pfnCallback, pvUser);
377 else
378 rc = VERR_NOT_SUPPORTED;
379
380 LogFlow(("RTLdrEnumDbgInfo: returns %Rrc\n", rc));
381 return rc;
382}
383RT_EXPORT_SYMBOL(RTLdrEnumDbgInfo);
384
385
386RTDECL(int) RTLdrEnumSegments(RTLDRMOD hLdrMod, PFNRTLDRENUMSEGS pfnCallback, void *pvUser)
387{
388 LogFlow(("RTLdrEnumSegments: hLdrMod=%RTldrm pfnCallback=%p pvUser=%p\n",
389 hLdrMod, pfnCallback, pvUser));
390
391 /*
392 * Validate input.
393 */
394 AssertMsgReturn(rtldrIsValid(hLdrMod), ("hLdrMod=%p\n", hLdrMod), VERR_INVALID_HANDLE);
395 AssertMsgReturn(RT_VALID_PTR(pfnCallback), ("pfnCallback=%p\n", pfnCallback), VERR_INVALID_PARAMETER);
396 PRTLDRMODINTERNAL pMod = (PRTLDRMODINTERNAL)hLdrMod;
397 //AssertMsgReturn(pMod->eState == LDR_STATE_OPENED, ("eState=%d\n", pMod->eState), VERR_WRONG_ORDER);
398
399 /*
400 * Do it.
401 */
402 int rc;
403 if (pMod->pOps->pfnEnumSegments)
404 rc = pMod->pOps->pfnEnumSegments(pMod, pfnCallback, pvUser);
405 else
406 rc = VERR_NOT_SUPPORTED;
407
408 LogFlow(("RTLdrEnumSegments: returns %Rrc\n", rc));
409 return rc;
410
411}
412RT_EXPORT_SYMBOL(RTLdrEnumSegments);
413
414
415RTDECL(int) RTLdrLinkAddressToSegOffset(RTLDRMOD hLdrMod, RTLDRADDR LinkAddress, uint32_t *piSeg, PRTLDRADDR poffSeg)
416{
417 LogFlow(("RTLdrLinkAddressToSegOffset: hLdrMod=%RTldrm LinkAddress=%RTptr piSeg=%p poffSeg=%p\n",
418 hLdrMod, LinkAddress, piSeg, poffSeg));
419
420 /*
421 * Validate input.
422 */
423 AssertMsgReturn(rtldrIsValid(hLdrMod), ("hLdrMod=%p\n", hLdrMod), VERR_INVALID_HANDLE);
424 AssertPtrReturn(piSeg, VERR_INVALID_POINTER);
425 AssertPtrReturn(poffSeg, VERR_INVALID_POINTER);
426
427 PRTLDRMODINTERNAL pMod = (PRTLDRMODINTERNAL)hLdrMod;
428 //AssertMsgReturn(pMod->eState == LDR_STATE_OPENED, ("eState=%d\n", pMod->eState), VERR_WRONG_ORDER);
429
430 *piSeg = UINT32_MAX;
431 *poffSeg = ~(RTLDRADDR)0;
432
433 /*
434 * Do it.
435 */
436 int rc;
437 if (pMod->pOps->pfnLinkAddressToSegOffset)
438 rc = pMod->pOps->pfnLinkAddressToSegOffset(pMod, LinkAddress, piSeg, poffSeg);
439 else
440 rc = VERR_NOT_SUPPORTED;
441
442 LogFlow(("RTLdrLinkAddressToSegOffset: returns %Rrc %#x:%RTptr\n", rc, *piSeg, *poffSeg));
443 return rc;
444}
445RT_EXPORT_SYMBOL(RTLdrLinkAddressToSegOffset);
446
447
448RTDECL(int) RTLdrLinkAddressToRva(RTLDRMOD hLdrMod, RTLDRADDR LinkAddress, PRTLDRADDR pRva)
449{
450 LogFlow(("RTLdrLinkAddressToRva: hLdrMod=%RTldrm LinkAddress=%RTptr pRva=%p\n",
451 hLdrMod, LinkAddress, pRva));
452
453 /*
454 * Validate input.
455 */
456 AssertMsgReturn(rtldrIsValid(hLdrMod), ("hLdrMod=%p\n", hLdrMod), VERR_INVALID_HANDLE);
457 AssertPtrReturn(pRva, VERR_INVALID_POINTER);
458
459 PRTLDRMODINTERNAL pMod = (PRTLDRMODINTERNAL)hLdrMod;
460 //AssertMsgReturn(pMod->eState == LDR_STATE_OPENED, ("eState=%d\n", pMod->eState), VERR_WRONG_ORDER);
461
462 *pRva = ~(RTLDRADDR)0;
463
464 /*
465 * Do it.
466 */
467 int rc;
468 if (pMod->pOps->pfnLinkAddressToRva)
469 rc = pMod->pOps->pfnLinkAddressToRva(pMod, LinkAddress, pRva);
470 else
471 rc = VERR_NOT_SUPPORTED;
472
473 LogFlow(("RTLdrLinkAddressToRva: returns %Rrc %RTptr\n", rc, *pRva));
474 return rc;
475}
476RT_EXPORT_SYMBOL(RTLdrLinkAddressToRva);
477
478
479RTDECL(int) RTLdrSegOffsetToRva(RTLDRMOD hLdrMod, uint32_t iSeg, RTLDRADDR offSeg, PRTLDRADDR pRva)
480{
481 LogFlow(("RTLdrSegOffsetToRva: hLdrMod=%RTldrm LinkAddress=%RTptr iSeg=%#x offSeg=%RTptr pRva=%p\n",
482 hLdrMod, iSeg, offSeg, pRva));
483
484 /*
485 * Validate input.
486 */
487 AssertMsgReturn(rtldrIsValid(hLdrMod), ("hLdrMod=%p\n", hLdrMod), VERR_INVALID_HANDLE);
488 AssertPtrReturn(pRva, VERR_INVALID_POINTER);
489
490 PRTLDRMODINTERNAL pMod = (PRTLDRMODINTERNAL)hLdrMod;
491 //AssertMsgReturn(pMod->eState == LDR_STATE_OPENED, ("eState=%d\n", pMod->eState), VERR_WRONG_ORDER);
492
493 *pRva = ~(RTLDRADDR)0;
494
495 /*
496 * Do it.
497 */
498 int rc;
499 if (pMod->pOps->pfnSegOffsetToRva)
500 rc = pMod->pOps->pfnSegOffsetToRva(pMod, iSeg, offSeg, pRva);
501 else
502 rc = VERR_NOT_SUPPORTED;
503
504 LogFlow(("RTLdrSegOffsetToRva: returns %Rrc %RTptr\n", rc, *pRva));
505 return rc;
506}
507RT_EXPORT_SYMBOL(RTLdrSegOffsetToRva);
508
509RTDECL(int) RTLdrRvaToSegOffset(RTLDRMOD hLdrMod, RTLDRADDR Rva, uint32_t *piSeg, PRTLDRADDR poffSeg)
510{
511 LogFlow(("RTLdrRvaToSegOffset: hLdrMod=%RTldrm Rva=%RTptr piSeg=%p poffSeg=%p\n",
512 hLdrMod, Rva, piSeg, poffSeg));
513
514 /*
515 * Validate input.
516 */
517 AssertMsgReturn(rtldrIsValid(hLdrMod), ("hLdrMod=%p\n", hLdrMod), VERR_INVALID_HANDLE);
518 AssertPtrReturn(piSeg, VERR_INVALID_POINTER);
519 AssertPtrReturn(poffSeg, VERR_INVALID_POINTER);
520
521 PRTLDRMODINTERNAL pMod = (PRTLDRMODINTERNAL)hLdrMod;
522 //AssertMsgReturn(pMod->eState == LDR_STATE_OPENED, ("eState=%d\n", pMod->eState), VERR_WRONG_ORDER);
523
524 *piSeg = UINT32_MAX;
525 *poffSeg = ~(RTLDRADDR)0;
526
527 /*
528 * Do it.
529 */
530 int rc;
531 if (pMod->pOps->pfnRvaToSegOffset)
532 rc = pMod->pOps->pfnRvaToSegOffset(pMod, Rva, piSeg, poffSeg);
533 else
534 rc = VERR_NOT_SUPPORTED;
535
536 LogFlow(("RTLdrRvaToSegOffset: returns %Rrc %#x:%RTptr\n", rc, *piSeg, *poffSeg));
537 return rc;
538}
539RT_EXPORT_SYMBOL(RTLdrRvaToSegOffset);
540
541
542RTDECL(int) RTLdrQueryProp(RTLDRMOD hLdrMod, RTLDRPROP enmProp, void *pvBuf, size_t cbBuf)
543{
544 AssertMsgReturn(rtldrIsValid(hLdrMod), ("hLdrMod=%p\n", hLdrMod), RTLDRENDIAN_INVALID);
545 PRTLDRMODINTERNAL pMod = (PRTLDRMODINTERNAL)hLdrMod;
546
547 /*
548 * Do some pre screening of the input
549 */
550 switch (enmProp)
551 {
552 case RTLDRPROP_UUID:
553 AssertReturn(cbBuf == sizeof(RTUUID), VERR_INVALID_PARAMETER);
554 break;
555 case RTLDRPROP_TIMESTAMP_SECONDS:
556 AssertReturn(cbBuf == sizeof(int32_t) || cbBuf == sizeof(int64_t), VERR_INVALID_PARAMETER);
557 break;
558 default:
559 AssertFailedReturn(VERR_INVALID_FUNCTION);
560 }
561 AssertPtrReturn(pvBuf, VERR_INVALID_POINTER);
562
563 /*
564 * Call the image specific worker, if there is one.
565 */
566 if (!pMod->pOps->pfnQueryProp)
567 return VERR_NOT_SUPPORTED;
568 return pMod->pOps->pfnQueryProp(pMod, enmProp, pvBuf, cbBuf);
569}
570RT_EXPORT_SYMBOL(RTLdrQueryProp);
571
572
573/**
574 * Internal method used by the IPRT debug bits.
575 *
576 * @returns IPRT status code.
577 * @param hLdrMod The loader handle which executable we wish to
578 * read from.
579 * @param pvBuf The output buffer.
580 * @param iDbgInfo The debug info ordinal number if the request
581 * corresponds exactly to a debug info part from
582 * pfnEnumDbgInfo. Otherwise, pass UINT32_MAX.
583 * @param off Where in the executable file to start reading.
584 * @param cb The number of bytes to read.
585 *
586 * @remarks Fixups will only be applied if @a iDbgInfo is specified.
587 */
588DECLHIDDEN(int) rtLdrReadAt(RTLDRMOD hLdrMod, void *pvBuf, uint32_t iDbgInfo, RTFOFF off, size_t cb)
589{
590 AssertMsgReturn(rtldrIsValid(hLdrMod), ("hLdrMod=%p\n", hLdrMod), VERR_INVALID_HANDLE);
591 PRTLDRMODINTERNAL pMod = (PRTLDRMODINTERNAL)hLdrMod;
592
593 if (iDbgInfo != UINT32_MAX)
594 {
595 AssertReturn(pMod->pOps->pfnReadDbgInfo, VERR_NOT_SUPPORTED);
596 return pMod->pOps->pfnReadDbgInfo(pMod, iDbgInfo, off, cb, pvBuf);
597 }
598
599 AssertReturn(pMod->pReader, VERR_NOT_SUPPORTED);
600 return pMod->pReader->pfnRead(pMod->pReader, pvBuf, cb, off);
601}
602
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