VirtualBox

source: vbox/trunk/src/VBox/Runtime/include/internal/ldr.h@ 73895

Last change on this file since 73895 was 73494, checked in by vboxsync, 6 years ago

IPRT: Added single stack frame unwind function to RTDbgMod and RTLdr, copying over the PoC from DBGFRStack.cpp. bugref:3897

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 21.5 KB
Line 
1/* $Id: ldr.h 73494 2018-08-04 19:41:30Z vboxsync $ */
2/** @file
3 * IPRT - Loader Internals.
4 */
5
6/*
7 * Copyright (C) 2006-2017 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#ifndef ___internal_ldr_h
28#define ___internal_ldr_h
29
30#include <iprt/types.h>
31#include "internal/magics.h"
32
33RT_C_DECLS_BEGIN
34
35
36/*******************************************************************************
37* Defined Constants And Macros *
38*******************************************************************************/
39#ifdef DOXYGEN_RUNNING
40/** @def LDR_WITH_NATIVE
41 * Define this to get native support. */
42# define LDR_WITH_NATIVE
43
44/** @def LDR_WITH_ELF32
45 * Define this to get 32-bit ELF support. */
46# define LDR_WITH_ELF32
47
48/** @def LDR_WITH_ELF64
49 * Define this to get 64-bit ELF support. */
50# define LDR_WITH_ELF64
51
52/** @def LDR_WITH_PE
53 * Define this to get 32-bit and 64-bit PE support. */
54# define LDR_WITH_PE
55
56/** @def LDR_WITH_LX
57 * Define this to get LX support. */
58# define LDR_WITH_LX
59
60/** @def LDR_WITH_MACHO
61 * Define this to get mach-o support (not implemented yet). */
62# define LDR_WITH_MACHO
63#endif /* DOXYGEN_RUNNING */
64
65#if defined(LDR_WITH_ELF32) || defined(LDR_WITH_ELF64)
66/** @def LDR_WITH_ELF
67 * This is defined if any of the ELF versions is requested.
68 */
69# define LDR_WITH_ELF
70#endif
71
72/* These two may clash with winnt.h. */
73#undef IMAGE_DOS_SIGNATURE
74#undef IMAGE_NT_SIGNATURE
75
76
77/** Little endian uint32_t ELF signature ("\x7fELF"). */
78#define IMAGE_ELF_SIGNATURE (0x7f | ('E' << 8) | ('L' << 16) | ('F' << 24))
79/** Little endian uint32_t PE signature ("PE\0\0"). */
80#define IMAGE_NT_SIGNATURE 0x00004550
81/** Little endian uint16_t LX signature ("LX") */
82#define IMAGE_LX_SIGNATURE ('L' | ('X' << 8))
83/** Little endian uint16_t LE signature ("LE") */
84#define IMAGE_LE_SIGNATURE ('L' | ('E' << 8))
85/** Little endian uint16_t NE signature ("NE") */
86#define IMAGE_NE_SIGNATURE ('N' | ('E' << 8))
87/** Little endian uint16_t MZ signature ("MZ"). */
88#define IMAGE_DOS_SIGNATURE ('M' | ('Z' << 8))
89
90
91/*******************************************************************************
92* Structures and Typedefs *
93*******************************************************************************/
94/**
95 * Loader state.
96 */
97typedef enum RTLDRSTATE
98{
99 /** Invalid. */
100 LDR_STATE_INVALID = 0,
101 /** Opened. */
102 LDR_STATE_OPENED,
103 /** The image can no longer be relocated. */
104 LDR_STATE_DONE,
105 /** The image was loaded, not opened. */
106 LDR_STATE_LOADED,
107 /** The usual 32-bit hack. */
108 LDR_STATE_32BIT_HACK = 0x7fffffff
109} RTLDRSTATE;
110
111
112/** Pointer to a loader item. */
113typedef struct RTLDRMODINTERNAL *PRTLDRMODINTERNAL;
114
115/**
116 * Loader module operations.
117 */
118typedef struct RTLDROPS
119{
120 /** The name of the executable format. */
121 const char *pszName;
122
123 /**
124 * Release any resources attached to the module.
125 * The caller will do RTMemFree on pMod on return.
126 *
127 * @returns iprt status code.
128 * @param pMod Pointer to the loader module structure.
129 * @remark Compulsory entry point.
130 */
131 DECLCALLBACKMEMBER(int, pfnClose)(PRTLDRMODINTERNAL pMod);
132
133 /**
134 * Gets a simple symbol.
135 * This entrypoint can be omitted if RTLDROPS::pfnGetSymbolEx() is provided.
136 *
137 * @returns iprt status code.
138 * @param pMod Pointer to the loader module structure.
139 * @param pszSymbol The symbol name.
140 * @param ppvValue Where to store the symbol value.
141 */
142 DECLCALLBACKMEMBER(int, pfnGetSymbol)(PRTLDRMODINTERNAL pMod, const char *pszSymbol, void **ppvValue);
143
144 /**
145 * Called when we're done with getting bits and relocating them.
146 * This is used to release resources used by the loader to support those actions.
147 *
148 * After this call none of the extended loader functions can be called.
149 *
150 * @returns iprt status code.
151 * @param pMod Pointer to the loader module structure.
152 * @remark This is an optional entry point.
153 */
154 DECLCALLBACKMEMBER(int, pfnDone)(PRTLDRMODINTERNAL pMod);
155
156 /**
157 * Enumerates the symbols exported by the module.
158 *
159 * @returns iprt status code, which might have been returned by pfnCallback.
160 * @param pMod Pointer to the loader module structure.
161 * @param fFlags Flags indicating what to return and such.
162 * @param pvBits Pointer to the bits returned by RTLDROPS::pfnGetBits(), optional.
163 * @param BaseAddress The image base addressto use when calculating the symbol values.
164 * @param pfnCallback The callback function which each symbol is to be
165 * fed to.
166 * @param pvUser User argument to pass to the enumerator.
167 * @remark This is an optional entry point.
168 */
169 DECLCALLBACKMEMBER(int, pfnEnumSymbols)(PRTLDRMODINTERNAL pMod, unsigned fFlags, const void *pvBits, RTUINTPTR BaseAddress,
170 PFNRTLDRENUMSYMS pfnCallback, void *pvUser);
171
172
173/* extended functions: */
174
175 /**
176 * Gets the size of the loaded image (i.e. in memory).
177 *
178 * @returns in memory size, in bytes.
179 * @returns ~(size_t)0 if it's not an extended image.
180 * @param pMod Pointer to the loader module structure.
181 * @remark Extended loader feature.
182 */
183 DECLCALLBACKMEMBER(size_t, pfnGetImageSize)(PRTLDRMODINTERNAL pMod);
184
185 /**
186 * Gets the image bits fixed up for a specified address.
187 *
188 * @returns iprt status code.
189 * @param pMod Pointer to the loader module structure.
190 * @param pvBits Where to store the bits. The size of this buffer is equal or
191 * larger to the value returned by pfnGetImageSize().
192 * @param BaseAddress The base address which the image should be fixed up to.
193 * @param pfnGetImport The callback function to use to resolve imports (aka unresolved externals).
194 * @param pvUser User argument to pass to the callback.
195 * @remark Extended loader feature.
196 */
197 DECLCALLBACKMEMBER(int, pfnGetBits)(PRTLDRMODINTERNAL pMod, void *pvBits, RTUINTPTR BaseAddress, PFNRTLDRIMPORT pfnGetImport, void *pvUser);
198
199 /**
200 * Relocate bits obtained using pfnGetBits to a new address.
201 *
202 * @returns iprt status code.
203 * @param pMod Pointer to the loader module structure.
204 * @param pvBits Where to store the bits. The size of this buffer is equal or
205 * larger to the value returned by pfnGetImageSize().
206 * @param NewBaseAddress The base address which the image should be fixed up to.
207 * @param OldBaseAddress The base address which the image is currently fixed up to.
208 * @param pfnGetImport The callback function to use to resolve imports (aka unresolved externals).
209 * @param pvUser User argument to pass to the callback.
210 * @remark Extended loader feature.
211 */
212 DECLCALLBACKMEMBER(int, pfnRelocate)(PRTLDRMODINTERNAL pMod, void *pvBits, RTUINTPTR NewBaseAddress, RTUINTPTR OldBaseAddress, PFNRTLDRIMPORT pfnGetImport, void *pvUser);
213
214 /**
215 * Gets a symbol with special base address and stuff.
216 * This entrypoint can be omitted if RTLDROPS::pfnGetSymbolEx() is provided and the special BaseAddress feature isn't supported.
217 *
218 * @returns iprt status code.
219 * @retval VERR_LDR_FORWARDER forwarder, use pfnQueryForwarderInfo. Buffer size
220 * in @a pValue.
221 * @param pMod Pointer to the loader module structure.
222 * @param pvBits Pointer to bits returned by RTLDROPS::pfnGetBits(), optional.
223 * @param BaseAddress The image base address to use when calculating the symbol value.
224 * @param iOrdinal Symbol table ordinal, UINT32_MAX if the symbol name
225 * should be used.
226 * @param pszSymbol The symbol name.
227 * @param pValue Where to store the symbol value.
228 * @remark Extended loader feature.
229 */
230 DECLCALLBACKMEMBER(int, pfnGetSymbolEx)(PRTLDRMODINTERNAL pMod, const void *pvBits, RTUINTPTR BaseAddress,
231 uint32_t iOrdinal, const char *pszSymbol, RTUINTPTR *pValue);
232
233 /**
234 * Query forwarder information on the specified symbol.
235 *
236 * This is an optional entrypoint.
237 *
238 * @returns iprt status code.
239 * @param pMod Pointer to the loader module structure.
240 * @param pvBits Pointer to bits returned by RTLDROPS::pfnGetBits(),
241 * optional.
242 * @param iOrdinal Symbol table ordinal of the forwarded symbol to query.
243 * UINT32_MAX if the symbol name should be used.
244 * @param pszSymbol The symbol name of the forwarded symbol to query.
245 * @param pInfo Where to return the forwarder information.
246 * @param cbInfo The size of the pInfo buffer. The pfnGetSymbolEx
247 * entrypoint returns the required size in @a pValue when
248 * the return code is VERR_LDR_FORWARDER.
249 * @remark Extended loader feature.
250 */
251 DECLCALLBACKMEMBER(int, pfnQueryForwarderInfo)(PRTLDRMODINTERNAL pMod, const void *pvBits, uint32_t iOrdinal,
252 const char *pszSymbol, PRTLDRIMPORTINFO pInfo, size_t cbInfo);
253
254 /**
255 * Enumerates the debug info contained in the module.
256 *
257 * @returns iprt status code, which might have been returned by pfnCallback.
258 * @param pMod Pointer to the loader module structure.
259 * @param pvBits Pointer to the bits returned by RTLDROPS::pfnGetBits(), optional.
260 * @param pfnCallback The callback function which each debug info part is
261 * to be fed to.
262 * @param pvUser User argument to pass to the enumerator.
263 * @remark This is an optional entry point that can be NULL.
264 */
265 DECLCALLBACKMEMBER(int, pfnEnumDbgInfo)(PRTLDRMODINTERNAL pMod, const void *pvBits,
266 PFNRTLDRENUMDBG pfnCallback, void *pvUser);
267
268 /**
269 * Enumerates the segments in the module.
270 *
271 * @returns iprt status code, which might have been returned by pfnCallback.
272 * @param pMod Pointer to the loader module structure.
273 * @param pfnCallback The callback function which each debug info part is
274 * to be fed to.
275 * @param pvUser User argument to pass to the enumerator.
276 * @remark This is an optional entry point that can be NULL.
277 */
278 DECLCALLBACKMEMBER(int, pfnEnumSegments)(PRTLDRMODINTERNAL pMod, PFNRTLDRENUMSEGS pfnCallback, void *pvUser);
279
280 /**
281 * Converts a link address to a segment:offset address.
282 *
283 * @returns IPRT status code.
284 *
285 * @param pMod Pointer to the loader module structure.
286 * @param LinkAddress The link address to convert.
287 * @param piSeg Where to return the segment index.
288 * @param poffSeg Where to return the segment offset.
289 * @remark This is an optional entry point that can be NULL.
290 */
291 DECLCALLBACKMEMBER(int, pfnLinkAddressToSegOffset)(PRTLDRMODINTERNAL pMod, RTLDRADDR LinkAddress,
292 uint32_t *piSeg, PRTLDRADDR poffSeg);
293
294 /**
295 * Converts a link address to a RVA.
296 *
297 * @returns IPRT status code.
298 *
299 * @param pMod Pointer to the loader module structure.
300 * @param LinkAddress The link address to convert.
301 * @param pRva Where to return the RVA.
302 * @remark This is an optional entry point that can be NULL.
303 */
304 DECLCALLBACKMEMBER(int, pfnLinkAddressToRva)(PRTLDRMODINTERNAL pMod, RTLDRADDR LinkAddress, PRTLDRADDR pRva);
305
306 /**
307 * Converts a segment:offset to a RVA.
308 *
309 * @returns IPRT status code.
310 *
311 * @param pMod Pointer to the loader module structure.
312 * @param iSeg The segment index.
313 * @param offSeg The segment offset.
314 * @param pRva Where to return the RVA.
315 * @remark This is an optional entry point that can be NULL.
316 */
317 DECLCALLBACKMEMBER(int, pfnSegOffsetToRva)(PRTLDRMODINTERNAL pMod, uint32_t iSeg, RTLDRADDR offSeg, PRTLDRADDR pRva);
318
319 /**
320 * Converts a RVA to a segment:offset.
321 *
322 * @returns IPRT status code.
323 *
324 * @param pMod Pointer to the loader module structure.
325 * @param Rva The RVA to convert.
326 * @param piSeg Where to return the segment index.
327 * @param poffSeg Where to return the segment offset.
328 * @remark This is an optional entry point that can be NULL.
329 */
330 DECLCALLBACKMEMBER(int, pfnRvaToSegOffset)(PRTLDRMODINTERNAL pMod, RTLDRADDR Rva, uint32_t *piSeg, PRTLDRADDR poffSeg);
331
332 /**
333 * Reads a debug info part (section) from the image.
334 *
335 * This is primarily needed for getting DWARF sections in ELF image with fixups
336 * applied and won't be required by most other loader backends.
337 *
338 * @returns IPRT status code.
339 *
340 * @param pMod Pointer to the loader module structure.
341 * @param pvBuf The buffer to read into.
342 * @param iDbgInfo The debug info ordinal number if the request
343 * corresponds exactly to a debug info part from
344 * pfnEnumDbgInfo. Otherwise, pass UINT32_MAX.
345 * @param off The offset into the image file.
346 * @param cb The number of bytes to read.
347 * @param pMod Pointer to the loader module structure.
348 */
349 DECLCALLBACKMEMBER(int, pfnReadDbgInfo)(PRTLDRMODINTERNAL pMod, uint32_t iDbgInfo, RTFOFF off, size_t cb, void *pvBuf);
350
351 /**
352 * Generic method for querying image properties.
353 *
354 * @returns IPRT status code.
355 * @retval VERR_NOT_SUPPORTED if the property query isn't supported (either all
356 * or that specific property).
357 * @retval VERR_NOT_FOUND the property was not found in the module.
358 *
359 * @param pMod Pointer to the loader module structure.
360 * @param enmProp The property to query (valid).
361 * @param pvBits Pointer to the bits returned by
362 * RTLDROPS::pfnGetBits(), optional.
363 * @param pvBuf Pointer to the input / output buffer. This is valid.
364 * Normally only used for returning data, but in some
365 * cases it also holds input.
366 * @param cbBuf The size of the buffer (valid as per
367 * property).
368 * @param pcbRet The number of bytes actually returned. If
369 * VERR_BUFFER_OVERFLOW is returned, this is set to the
370 * required buffer size.
371 */
372 DECLCALLBACKMEMBER(int, pfnQueryProp)(PRTLDRMODINTERNAL pMod, RTLDRPROP enmProp, void const *pvBits,
373 void *pvBuf, size_t cbBuf, size_t *pcbRet);
374
375 /**
376 * Verify the image signature.
377 *
378 * This may permform additional integrity checks on the image structures that
379 * was not done when opening the image.
380 *
381 * @returns IPRT status code.
382 * @retval VERR_LDRVI_NOT_SIGNED if not signed.
383 *
384 * @param pMod Pointer to the loader module structure.
385 * @param pfnCallback Callback that does the signature and certificate
386 * verficiation.
387 * @param pvUser User argument for the callback.
388 * @param pErrInfo Pointer to an error info buffer. Optional.
389 */
390 DECLCALLBACKMEMBER(int, pfnVerifySignature)(PRTLDRMODINTERNAL pMod, PFNRTLDRVALIDATESIGNEDDATA pfnCallback, void *pvUser,
391 PRTERRINFO pErrInfo);
392
393 /**
394 * Calculate the image hash according the image signing rules.
395 *
396 * @returns IPRT status code.
397 * @param pMod The module handle.
398 * @param enmDigest Which kind of digest.
399 * @param pszDigest Where to store the image digest.
400 * @param cbDigest Size of the buffer @a pszDigest points at.
401 */
402 DECLCALLBACKMEMBER(int, pfnHashImage)(PRTLDRMODINTERNAL pMod, RTDIGESTTYPE enmDigest, char *pszDigest, size_t cbDigest);
403
404 /**
405 * Try use unwind information to unwind one frame.
406 *
407 * @returns IPRT status code. Last informational status from stack reader callback.
408 * @retval VERR_DBG_NO_UNWIND_INFO if the module contains no unwind information.
409 * @retval VERR_DBG_UNWIND_INFO_NOT_FOUND if no unwind information was found
410 * for the location given by iSeg:off.
411 *
412 * @param pMod Pointer to the module structure.
413 * @param pvBits Pointer to the bits returned by
414 * RTLDROPS::pfnGetBits(), optional.
415 * @param iSeg The segment number of the program counter. UINT32_MAX for RVA.
416 * @param off The offset into @a iSeg. Together with @a iSeg
417 * this corresponds to the RTDBGUNWINDSTATE::uPc
418 * value pointed to by @a pState.
419 * @param pState The unwind state to work.
420 *
421 * @sa RTLdrUnwindFrame, RTDbgModUnwindFrame
422 */
423 DECLCALLBACKMEMBER(int, pfnUnwindFrame)(PRTLDRMODINTERNAL pMod, void const *pvBits, uint32_t iSeg, RTUINTPTR off,
424 PRTDBGUNWINDSTATE pState);
425
426 /** Dummy entry to make sure we've initialized it all. */
427 RTUINT uDummy;
428} RTLDROPS;
429typedef RTLDROPS *PRTLDROPS;
430typedef const RTLDROPS *PCRTLDROPS;
431
432
433/**
434 * Loader module core.
435 */
436typedef struct RTLDRMODINTERNAL
437{
438 /** The loader magic value (RTLDRMOD_MAGIC). */
439 uint32_t u32Magic;
440 /** State. */
441 RTLDRSTATE eState;
442 /** Loader ops. */
443 PCRTLDROPS pOps;
444 /** Pointer to the reader instance. This is NULL for native image. */
445 PRTLDRREADER pReader;
446 /** Image format. */
447 RTLDRFMT enmFormat;
448 /** Image type. */
449 RTLDRTYPE enmType;
450 /** Image endianness. */
451 RTLDRENDIAN enmEndian;
452 /** Image target architecture. */
453 RTLDRARCH enmArch;
454} RTLDRMODINTERNAL;
455
456
457/**
458 * Validates that a loader module handle is valid.
459 *
460 * @returns true if valid.
461 * @returns false if invalid.
462 * @param hLdrMod The loader module handle.
463 */
464DECLINLINE(bool) rtldrIsValid(RTLDRMOD hLdrMod)
465{
466 return VALID_PTR(hLdrMod)
467 && ((PRTLDRMODINTERNAL)hLdrMod)->u32Magic == RTLDRMOD_MAGIC;
468}
469
470
471/**
472 * Native loader module.
473 */
474typedef struct RTLDRMODNATIVE
475{
476 /** The core structure. */
477 RTLDRMODINTERNAL Core;
478 /** The native handle. */
479 uintptr_t hNative;
480 /** The load flags (RTLDRLOAD_FLAGS_XXX). */
481 uint32_t fFlags;
482} RTLDRMODNATIVE;
483/** Pointer to a native module. */
484typedef RTLDRMODNATIVE *PRTLDRMODNATIVE;
485
486/** @copydoc RTLDROPS::pfnGetSymbol */
487DECLCALLBACK(int) rtldrNativeGetSymbol(PRTLDRMODINTERNAL pMod, const char *pszSymbol, void **ppvValue);
488/** @copydoc RTLDROPS::pfnClose */
489DECLCALLBACK(int) rtldrNativeClose(PRTLDRMODINTERNAL pMod);
490
491/**
492 * Load a native module using the native loader.
493 *
494 * @returns iprt status code.
495 * @param pszFilename The image filename.
496 * @param phHandle Where to store the module handle on success.
497 * @param fFlags RTLDRLOAD_FLAGS_XXX.
498 * @param pErrInfo Where to return extended error information. Optional.
499 */
500int rtldrNativeLoad(const char *pszFilename, uintptr_t *phHandle, uint32_t fFlags, PRTERRINFO pErrInfo);
501
502/**
503 * Load a system library.
504 *
505 * @returns iprt status code.
506 * @param pszFilename The image filename.
507 * @param pszExt Extension to add. NULL if none.
508 * @param fFlags RTLDRLOAD_FLAGS_XXX.
509 * @param phLdrMod Where to return the module handle on success.
510 */
511int rtldrNativeLoadSystem(const char *pszFilename, const char *pszExt, uint32_t fFlags, PRTLDRMOD phLdrMod);
512
513int rtldrPEOpen(PRTLDRREADER pReader, uint32_t fFlags, RTLDRARCH enmArch, RTFOFF offNtHdrs, PRTLDRMOD phLdrMod, PRTERRINFO pErrInfo);
514int rtldrELFOpen(PRTLDRREADER pReader, uint32_t fFlags, RTLDRARCH enmArch, PRTLDRMOD phLdrMod, PRTERRINFO pErrInfo);
515int rtldrkLdrOpen(PRTLDRREADER pReader, uint32_t fFlags, RTLDRARCH enmArch, PRTLDRMOD phLdrMod, PRTERRINFO pErrInfo);
516/*int rtldrLXOpen(PRTLDRREADER pReader, uint32_t fFlags, RTLDRARCH enmArch, RTFOFF offLX, PRTLDRMOD phLdrMod);
517int rtldrMachoOpen(PRTLDRREADER pReader, uint32_t fFlags, RTLDRARCH enmArch, RTFOFF offSomething, PRTLDRMOD phLdrMod);*/
518
519
520DECLHIDDEN(int) rtLdrReadAt(RTLDRMOD hLdrMod, void *pvBuf, uint32_t iDbgInfo, RTFOFF off, size_t cb);
521
522RT_C_DECLS_END
523
524#endif
525
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