dbgas.cpp revision 9b19ad593b379ebfcc8273f85b90763b14b1da63
/* $Id$ */
/** @file
* IPRT - Debug Address Space.
*/
/*
* Copyright (C) 2009 Sun Microsystems, Inc.
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* The contents of this file may alternatively be used under the terms
* of the Common Development and Distribution License Version 1.0
* (CDDL) only, as it comes in the "COPYING.CDDL" file of the
* VirtualBox OSE distribution, in which case the provisions of the
* CDDL are applicable instead of those of the GPL.
*
* You may elect to license modified versions of this file under the
* terms and conditions of either the GPL or the CDDL or both.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
* Clara, CA 95054 USA or visit http://www.sun.com if you need
* additional information or have any questions.
*/
/*******************************************************************************
* Header Files *
*******************************************************************************/
#include <iprt/semaphore.h>
/*******************************************************************************
* Structures and Typedefs *
*******************************************************************************/
/** Pointer to a module table entry. */
typedef struct RTDBGASMOD *PRTDBGASMOD;
/** Pointer to an address space mapping node. */
typedef struct RTDBGASMAP *PRTDBGASMAP;
/** Pointer to a name head. */
typedef struct RTDBGASNAME *PRTDBGASNAME;
/**
* Module entry.
*/
typedef struct RTDBGASMOD
{
/** Node core, the module handle is the key. */
/** Pointer to the first mapping of the module or a segment within it. */
/** Pointer to the next module with an identical name. */
/** The index into RTDBGASINT::papModules. */
} RTDBGASMOD;
/**
* An address space mapping, either of a full module or a segment.
*/
typedef struct RTDBGASMAP
{
/** The AVL node core. Contains the address range. */
/** Pointer to the next mapping of the module. */
/** Pointer to the module. */
/** Which segment in the module.
* This is NIL_RTDBGSEGIDX when the entire module is mapped. */
} RTDBGASMAP;
/**
* Name in the address space.
*/
typedef struct RTDBGASNAME
{
/** The string space node core.*/
/** The list of nodes */
} RTDBGASNAME;
/**
* Debug address space instance.
*/
typedef struct RTDBGASINT
{
/** Magic value (RTDBGAS_MAGIC). */
/** The number of reference to this address space. */
/** Handle of the read-write lock. */
/** Number of modules in the module address space. */
/** Pointer to the module table.
* The valid array length is given by cModules. */
/** AVL tree translating module handles to module entries. */
/** AVL tree mapping addresses to modules. */
/** Names of the modules in the name space. */
/** The first address the AS. */
/** The last address in the AS. */
/** The name of the address space. (variable length) */
char szName[1];
} RTDBGASINT;
/** Pointer to an a debug address space instance. */
typedef RTDBGASINT *PRTDBGASINT;
/*******************************************************************************
* Defined Constants And Macros *
*******************************************************************************/
/** Validates an address space handle and returns rc if not valid. */
do { \
} while (0)
/** Locks the address space for reading. */
#define RTDBGAS_LOCK_READ(pDbgAs) \
do { \
} while (0)
/** Unlocks the address space after reading. */
#define RTDBGAS_UNLOCK_READ(pDbgAs) \
do { \
} while (0)
/** Locks the address space for writing. */
#define RTDBGAS_LOCK_WRITE(pDbgAs) \
do { \
} while (0)
/** Unlocks the address space after writing. */
#define RTDBGAS_UNLOCK_WRITE(pDbgAs) \
do { \
} while (0)
/*******************************************************************************
* Internal Functions *
*******************************************************************************/
/**
* Creates an empty address space.
*
* @returns IPRT status code.
*
* @param phDbgAs Where to store the address space handle on success.
* @param FirstAddr The first address in the address space.
* @param LastAddr The last address in the address space.
* @param pszName The name of the address space.
*/
RTDECL(int) RTDbgAsCreate(PRTDBGAS phDbgAs, RTUINTPTR FirstAddr, RTUINTPTR LastAddr, const char *pszName)
{
/*
* Input validation.
*/
/*
* Allocate memory for the instance data.
*/
if (!pDbgAs)
return VERR_NO_MEMORY;
/* initalize it. */
if (RT_SUCCESS(rc))
{
return VINF_SUCCESS;
}
return rc;
}
/**
* Variant of RTDbgAsCreate that takes a name format string.
*
* @returns IPRT status code.
*
* @param phDbgAs Where to store the address space handle on success.
* @param FirstAddr The first address in the address space.
* @param LastAddr The last address in the address space.
* @param pszNameFmt The name format of the address space.
* @param va Format arguments.
*/
RTDECL(int) RTDbgAsCreateV(PRTDBGAS phDbgAs, RTUINTPTR FirstAddr, RTUINTPTR LastAddr, const char *pszNameFmt, va_list va)
{
char *pszName;
if (!pszName)
return VERR_NO_MEMORY;
return rc;
}
/**
* Variant of RTDbgAsCreate that takes a name format string.
*
* @returns IPRT status code.
*
* @param phDbgAs Where to store the address space handle on success.
* @param FirstAddr The first address in the address space.
* @param LastAddr The last address in the address space.
* @param pszNameFmt The name format of the address space.
* @param ... Format arguments.
*/
RTDECL(int) RTDbgAsCreateF(PRTDBGAS phDbgAs, RTUINTPTR FirstAddr, RTUINTPTR LastAddr, const char *pszNameFmt, ...)
{
return rc;
}
/**
* Callback used by RTDbgAsDestroy to free all mapping nodes.
*
* @returns 0
* @param pNode The map node.
* @param pvUser NULL.
*/
{
return 0;
}
/**
* Callback used by RTDbgAsDestroy to free all name space nodes.
*
* @returns 0
* @param pStr The name node.
* @param pvUser NULL.
*/
{
return 0;
}
/**
* Destroys the address space.
*
* This means unlinking all the modules it currently contains, potentially
* causing some or all of them to be destroyed as they are managed by
* reference counting.
*
* @param pDbgAs The address space instance to be destroyed.
*/
{
/*
* Mark the address space invalid and release all the modules.
*/
while (i-- > 0)
{
{
}
}
}
/**
* Retains another reference to the address space.
*
* @returns New reference count, UINT32_MAX on invalid handle (asserted).
*
* @param hDbgAs The address space handle.
*
* @remarks Will not take any locks.
*/
{
}
/**
* Release a reference to the address space.
*
* When the reference count reaches zero, the address space is destroyed.
* That means unlinking all the modules it currently contains, potentially
* causing some or all of them to be destroyed as they are managed by
* reference counting.
*
* @returns New reference count, UINT32_MAX on invalid handle (asserted).
*
* @param hDbgAs The address space handle. The NIL handle is quietly
* ignored and 0 is returned.
*
* @remarks Will not take any locks.
*/
{
if (hDbgAs == NIL_RTDBGAS)
return 0;
if (!cRefs)
return cRefs;
}
/**
* Gets the name of an address space.
*
* @returns read only address space name.
* NULL if hDbgAs is invalid.
*
* @param hDbgAs The address space handle.
*
* @remarks Will not take any locks.
*/
{
}
/**
* Gets the first address in an address space.
*
* @returns The address.
* 0 if hDbgAs is invalid.
*
* @param hDbgAs The address space handle.
*
* @remarks Will not take any locks.
*/
{
}
/**
* Gets the last address in an address space.
*
* @returns The address.
* 0 if hDbgAs is invalid.
*
* @param hDbgAs The address space handle.
*
* @remarks Will not take any locks.
*/
{
}
/**
* Gets the number of modules in the address space.
*
* This can be used together with RTDbgAsModuleByIndex
* to enumerate the modules.
*
* @returns The number of modules.
*
* @param hDbgAs The address space handle.
*
* @remarks Will not take any locks.
*/
{
}
/**
* Common worker for RTDbgAsModuleLink and RTDbgAsModuleLinkSeg.
*
* @returns IPRT status.
* @param pDbgAs Pointer to the address space instance data.
* @param hDbgMod The module to link.
* @param iSeg The segment to link or NIL if all.
* @param Addr The address we're linking it at.
* @param cb The size of what we're linking.
* @param pszName The name of the module.
* @param fFlags See RTDBGASLINK_FLAGS_*.
*
* @remarks The caller must have locked the address space for writing.
*/
{
/*
* Check that the requested space is undisputed.
*/
for (;;)
{
PRTDBGASMAP pAdjMod = (PRTDBGASMAP)RTAvlrUIntPtrGetBestFit(&pDbgAs->MapTree, Addr, false /* fAbove */);
if ( pAdjMod
{
if (!(fFlags & RTDBGASLINK_FLAGS_REPLACE))
return VERR_ADDRESS_CONFLICT;
continue;
}
if ( pAdjMod
{
if (!(fFlags & RTDBGASLINK_FLAGS_REPLACE))
return VERR_ADDRESS_CONFLICT;
continue;
}
break;
}
/*
* First, create or find the module table entry.
*/
if (!pMod)
{
/*
* Ok, we need a new entry. Grow the table if necessary.
*/
{
void *pvNew = RTMemRealloc(pDbgAs->papModules, sizeof(pDbgAs->papModules[0]) * (pDbgAs->cModules + 32));
if (!pvNew)
return VERR_NO_MEMORY;
}
if (!pMod)
return VERR_NO_MEMORY;
{
AssertFailed();
return VERR_INTERNAL_ERROR;
}
/*
* Add it to the name space.
*/
if (!pName)
{
if (!pName)
{
return VERR_NO_MEMORY;
}
AssertFailed();
}
else
{
/* quick, but unfair. */
}
}
/*
* Create a mapping node.
*/
int rc;
if (pMap)
{
{
return VINF_SUCCESS;
}
AssertFailed();
}
else
rc = VERR_NO_MEMORY;
/*
* Unlink the module if this was the only mapping.
*/
return rc;
}
/**
* Links a module into the address space at the give address.
*
* The size of the mapping is determined using RTDbgModImageSize().
*
* @returns IPRT status code.
* @retval VERR_OUT_OF_RANGE if the specified address will put the module
* outside the address space.
* @retval VERR_ADDRESS_CONFLICT if the mapping clashes with existing mappings.
*
* @param hDbgAs The address space handle.
* @param hDbgMod The module handle of the module to be linked in.
* @param ImageAddr The address to link the module at.
* @param fFlags See RTDBGASLINK_FLAGS_*.
*/
RTDECL(int) RTDbgAsModuleLink(RTDBGAS hDbgAs, RTDBGMOD hDbgMod, RTUINTPTR ImageAddr, uint32_t fFlags)
{
/*
* Validate input.
*/
if (!pszName)
return VERR_INVALID_HANDLE;
if (!cb)
return VERR_OUT_OF_RANGE;
return VERR_OUT_OF_RANGE;
/*
* Invoke worker common with RTDbgAsModuleLinkSeg.
*/
return rc;
}
/**
* Links a segment into the address space at the give address.
*
* The size of the mapping is determined using RTDbgModSegmentSize().
*
* @returns IPRT status code.
* @retval VERR_OUT_OF_RANGE if the specified address will put the module
* outside the address space.
* @retval VERR_ADDRESS_CONFLICT if the mapping clashes with existing mappings.
*
* @param hDbgAs The address space handle.
* @param hDbgMod The module handle.
* @param iSeg The segment number (0-based) of the segment to be
* linked in.
* @param SegAddr The address to link the segment at.
* @param fFlags See RTDBGASLINK_FLAGS_*.
*/
RTDECL(int) RTDbgAsModuleLinkSeg(RTDBGAS hDbgAs, RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg, RTUINTPTR SegAddr, uint32_t fFlags)
{
/*
* Validate input.
*/
if (!pszName)
return VERR_INVALID_HANDLE;
if (!cb)
return VERR_OUT_OF_RANGE;
return VERR_OUT_OF_RANGE;
/*
* Invoke worker common with RTDbgAsModuleLinkSeg.
*/
return rc;
}
/**
* Worker for RTDbgAsModuleUnlink, RTDbgAsModuleUnlinkByAddr and rtDbgAsModuleLinkCommon.
*
* @param pDbgAs Pointer to the address space instance data.
* @param pMod The module to unlink.
*
* @remarks The caller must have locked the address space for writing.
*/
{
/*
* Unlink it from the name.
*/
else
{
break;
}
/*
* Free the name if this was the last reference to it.
*/
{
}
/*
* Remove it from the module handle tree.
*/
/*
* Remove it from the module table by replacing it by the last entry.
*/
{
}
/*
* Free it.
*/
}
/**
* Worker for RTDbgAsModuleUnlink and RTDbgAsModuleUnlinkByAddr.
*
* @param pDbgAs Pointer to the address space instance data.
* @param pMap The map to unlink and free.
*
* @remarks The caller must have locked the address space for writing.
*/
{
/* remove from the tree */
/* unlink */
else
{
bool fFound = false;
{
fFound = true;
break;
}
}
/* free it */
}
/**
* Worker for RTDbgAsModuleUnlinkByAddr and rtDbgAsModuleLinkCommon that
* unlinks a single mapping and releases the module if it's the last one.
*
* @param pDbgAs The address space instance.
* @param pMap The mapping to unlink.
*
* @remarks The caller must have locked the address space for writing.
*/
{
/*
* Unlink it from the address space.
* Unlink the module as well if it's the last mapping it has.
*/
}
/**
* Unlinks all the mappings of a module from the address space.
*
* @returns IPRT status code.
* @retval VERR_NOT_FOUND if the module wasn't found.
*
* @param hDbgAs The address space handle.
* @param hDbgMod The module handle of the module to be unlinked.
*/
{
/*
* Validate input.
*/
if (hDbgMod == NIL_RTDBGMOD)
return VINF_SUCCESS;
if (!pMod)
{
return VERR_NOT_FOUND;
}
/*
* Unmap all everything and release the module.
*/
return VINF_SUCCESS;
}
/**
* Unlinks the mapping at the specified address.
*
* @returns IPRT status code.
* @retval VERR_NOT_FOUND if no module or segment is mapped at that address.
*
* @param hDbgAs The address space handle.
* @param Addr The address within the mapping to be unlinked.
*/
{
/*
* Validate input.
*/
if (pMap)
{
return VERR_NOT_FOUND;
}
/*
* Hand it to
*/
return VINF_SUCCESS;
}
/**
* Get a the handle of a module in the address space by is index.
*
* @returns A retained handle to the specified module. The caller must release
* the returned reference.
* NIL_RTDBGMOD if invalid index or handle.
*
* @param hDbgAs The address space handle.
* @param iModule The index of the module to get.
*
* @remarks The module indexes may change after calls to RTDbgAsModuleLink,
* RTDbgAsModuleLinkSeg, RTDbgAsModuleUnlink and
* RTDbgAsModuleUnlinkByAddr.
*/
{
/*
* Validate input.
*/
{
return NIL_RTDBGMOD;
}
/*
* Get, retain and return it.
*/
return hMod;
}
/**
* Queries mapping module information by handle.
*
* @returns IPRT status code.
* @retval VERR_NOT_FOUND if no mapping was found at the specified address.
*
* @param hDbgAs The address space handle.
* @param Addr Address within the mapping of the module or segment.
* @param phMod Where to the return the retained module handle.
* Optional.
* @param pAddr Where to return the base address of the mapping.
* Optional.
* @param piSeg Where to return the segment index. This is set to
* NIL if the entire module is mapped as a single
* mapping. Optional.
*/
RTDECL(int) RTDbgAsModuleByAddr(RTDBGAS hDbgAs, RTUINTPTR Addr, PRTDBGMOD phMod, PRTUINTPTR pAddr, PRTDBGSEGIDX piSeg)
{
/*
* Validate input.
*/
if (pMap)
{
return VERR_NOT_FOUND;
}
/*
* Set up the return values.
*/
if (phMod)
{
}
if (pAddr)
if (piSeg)
return VINF_SUCCESS;
}
/**
* Queries mapping module information by name.
*
* @returns IPRT status code.
* @retval VERR_NOT_FOUND if no mapping was found at the specified address.
* @retval VERR_OUT_OF_RANGE if the name index was out of range.
*
* @param hDbgAs The address space handle.
* @param pszName The module name.
* @param iName There can be more than one module by the same name
* in an address space. This argument indicates which
* is ment. (0 based)
* @param phMod Where to the return the retained module handle.
*/
RTDECL(int) RTDbgAsModuleByName(RTDBGAS hDbgAs, const char *pszName, uint32_t iName, PRTDBGMOD phMod)
{
/*
* Validate input.
*/
if (!pName)
{
return VERR_NOT_FOUND;
}
while (iName-- > 0)
{
if (!pMod)
{
return VERR_OUT_OF_RANGE;
}
}
/*
* Get, retain and return it.
*/
return VINF_SUCCESS;
}
/**
* Queries mapping information for a module given by index.
*
* @returns IRPT status code.
* @retval VERR_INVALID_HANDLE if hDbgAs is invalid.
* @retval VERR_OUT_OF_RANGE if the name index was out of range.
* @retval VINF_BUFFER_OVERFLOW if the array is too small and the returned
* information is incomplete.
*
* @param hDbgAs The address space handle.
* @param iModule The index of the module to get.
* @param paMappings Where to return the mapping information. The buffer
* size is given by *pcMappings.
* @param pcMappings IN: Size of the paMappings array. OUT: The number of
* entries returned.
* @param fFlags Flags for reserved for future use. MBZ.
*
* @remarks See remarks for RTDbgAsModuleByIndex regarding the volatility of the
* iModule parameter.
*/
RTDECL(int) RTDbgAsModuleQueryMapByIndex(RTDBGAS hDbgAs, uint32_t iModule, PRTDBGASMAPINFO paMappings, uint32_t *pcMappings, uint32_t fFlags)
{
/*
* Validate input.
*/
{
return VERR_OUT_OF_RANGE;
}
/*
* Copy the mapping information about the module.
*/
int rc = VINF_SUCCESS;
while (pMap)
{
{
break;
}
cMaps++;
}
*pcMappings = cMaps;
return rc;
}
/**
* Internal worker that looks up and retains a module.
*
* @returns Module handle, NIL_RTDBGMOD if not found.
* @param pDbgAs The address space instance data.
* @param Addr Address within the module.
* @param piSeg where to return the segment index.
* @param poffSeg Where to return the segment offset.
* @param pMapAddr The mapping address (RTDBGASMAP::Core.Key).
*/
DECLINLINE(RTDBGMOD) rtDbgAsModuleByAddr(PRTDBGASINT pDbgAs, RTUINTPTR Addr, PRTDBGSEGIDX piSeg, PRTUINTPTR poffSeg, PRTUINTPTR pMapAddr)
{
if (pMap)
{
if (pMapAddr)
}
return hMod;
}
/**
*
* @param pSymbol The returned symbol info.
* @param pMap The mapping record.
* @param hDbgMod The module handle.
* @param MapAddr The mapping address.
* @param iMapSeg The segment that's mapped, NIL_RTDBGSEGIDX or
* RTDBGSEGIDX_RVA if the whole module is mapped here.
*/
{
if (iSeg == RTDBGSEGIDX_ABS)
return;
if (iSeg == RTDBGSEGIDX_RVA)
{
if ( iMapSeg == RTDBGSEGIDX_RVA
|| iMapSeg == NIL_RTDBGSEGIDX)
else
{
}
}
else
{
if ( iMapSeg != RTDBGSEGIDX_RVA
&& iMapSeg != NIL_RTDBGSEGIDX)
{
}
else
{
}
}
}
/**
*
* @param pSymbol The returned symbol info.
* @param hDbgMod The module handle.
* @param MapAddr The mapping address.
* @param iMapSeg The segment that's mapped, NIL_RTDBGSEGIDX if the
* whole module is mapped here.
*/
DECLINLINE(void) rtDbgAsAdjustSymbolValue(PRTDBGSYMBOL pSymbol, RTDBGMOD hDbgMod, RTUINTPTR MapAddr, RTDBGSEGIDX iMapSeg)
{
}
/**
*
* @param pLine The returned line number info.
* @param hDbgMod The module handle.
* @param MapAddr The mapping address.
* @param iMapSeg The segment that's mapped, NIL_RTDBGSEGIDX if the
* whole module is mapped here.
*/
DECLINLINE(void) rtDbgAsAdjustLineAddress(PRTDBGLINE pLine, RTDBGMOD hDbgMod, RTUINTPTR MapAddr, RTDBGSEGIDX iMapSeg)
{
}
/**
* Adds a symbol to a module in the address space.
*
* @returns IPRT status code. See RTDbgModSymbolAdd for more specific ones.
* @retval VERR_INVALID_HANDLE if hDbgAs is invalid.
* @retval VERR_NOT_FOUND if no module was found at the specified address.
* @retval VERR_NOT_SUPPORTED if the module interpret doesn't support adding
* custom symbols.
*
* @param hDbgAs The address space handle.
* @param pszSymbol The symbol name.
* @param Addr The address of the symbol.
* @param cb The size of the symbol.
* @param fFlags Symbol flags.
*/
RTDECL(int) RTDbgAsSymbolAdd(RTDBGAS hDbgAs, const char *pszSymbol, RTUINTPTR Addr, RTUINTPTR cb, uint32_t fFlags, uint32_t *piOrdinal)
{
/*
* Validate input and resolve the address.
*/
if (hMod == NIL_RTDBGMOD)
return VERR_NOT_FOUND;
/*
* Forward the call.
*/
return rc;
}
/**
* Query a symbol by address.
*
* @returns IPRT status code. See RTDbgModSymbolAddr for more specific ones.
* @retval VERR_INVALID_HANDLE if hDbgAs is invalid.
* @retval VERR_NOT_FOUND if the address couldn't be mapped to a module.
*
* @param hDbgAs The address space handle.
* @param Addr The address which closest symbol is requested.
* @param poffDisp Where to return the distance between the symbol
* and address. Optional.
* @param pSymbol Where to return the symbol info.
* @param phMod Where to return the module handle. Optional.
*/
RTDECL(int) RTDbgAsSymbolByAddr(RTDBGAS hDbgAs, RTUINTPTR Addr, PRTINTPTR poffDisp, PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod)
{
/*
* Validate input and resolve the address.
*/
if (hMod == NIL_RTDBGMOD)
{
if (phMod)
*phMod = NIL_RTDBGMOD;
return VERR_NOT_FOUND;
}
/*
* Forward the call.
*/
if (RT_SUCCESS(rc))
if (phMod)
else
return rc;
}
/**
* Query a symbol by address.
*
* @returns IPRT status code. See RTDbgModSymbolAddrA for more specific ones.
* @retval VERR_INVALID_HANDLE if hDbgAs is invalid.
* @retval VERR_NOT_FOUND if the address couldn't be mapped to a module.
*
* @param hDbgAs The address space handle.
* @param Addr The address which closest symbol is requested.
* @param poffDisp Where to return the distance between the symbol
* and address. Optional.
* @param ppSymbol Where to return the pointer to the allocated
* symbol info. Always set. Free with RTDbgSymbolFree.
* @param phMod Where to return the module handle. Optional.
*/
RTDECL(int) RTDbgAsSymbolByAddrA(RTDBGAS hDbgAs, RTUINTPTR Addr, PRTINTPTR poffDisp, PRTDBGSYMBOL *ppSymbol, PRTDBGMOD phMod)
{
/*
* Validate input and resolve the address.
*/
if (hMod == NIL_RTDBGMOD)
{
if (phMod)
*phMod = NIL_RTDBGMOD;
return VERR_NOT_FOUND;
}
/*
* Forward the call.
*/
if (RT_SUCCESS(rc))
if (phMod)
else
return rc;
}
/**
* Creates a snapshot of the module table on the temporary heap.
*
* The caller must release all the module handles before freeing the table
* using RTMemTmpFree.
*
* @returns Module table snaphot.
* @param pDbgAs The address space instance data.
* @param pcModules Where to return the number of modules.
*/
{
if (pahModules)
{
while (iMod-- > 0)
{
}
}
return pahModules;
}
/**
* adjust it's Value field accordingly.
*
* @returns true / false success indicator.
* @param pDbgAs The address space.
* @param hDbgMod The module handle.
* @param pSymbol The symbol info.
*/
static bool rtDbgAsFindMappingAndAdjustSymbolValue(PRTDBGASINT pDbgAs, RTDBGMOD hDbgMod, PRTDBGSYMBOL pSymbol)
{
/*
* Absolute segments needs no fixing.
*/
if (iSeg == RTDBGSEGIDX_ABS)
return true;
/*
* Lookup up the module by it's handle and iterate the mappings looking for one
* that either encompasses the entire module or the segment in question.
*/
if (pMod)
{
{
/* Exact segment match or full-mapping. */
{
return true;
}
/* Symbol uses RVA and the mapping doesn't, see if it's in the mapped segment. */
if (iSeg == RTDBGSEGIDX_RVA)
{
{
return true;
}
}
}
}
/* else: Unmapped while we were searching. */
return false;
}
/**
* Query a symbol by name.
*
* @returns IPRT status code.
* @retval VERR_SYMBOL_NOT_FOUND if not found.
*
* @param hDbgAs The address space handle.
* @param pszSymbol The symbol name. It is possible to limit the scope
* of the search by prefixing the symbol with a module
* name pattern followed by a bang (!) character.
* RTStrSimplePatternNMatch is used for the matching.
* @param pSymbol Where to return the symbol info.
* @param phMod Where to return the module handle. Optional.
*/
RTDECL(int) RTDbgAsSymbolByName(RTDBGAS hDbgAs, const char *pszSymbol, PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod)
{
/*
* Validate input.
*/
/*
* Look for module pattern.
*/
const char *pachModPat = NULL;
if (pszBang)
{
if (!*pszSymbol)
/* Note! Zero length module -> no pattern -> escape for symbol with '!'. */
}
/*
* Iterate the modules, looking for the symbol.
*/
if (!pahModules)
return VERR_NO_TMP_MEMORY;
{
if ( cchModPat == 0
{
if (RT_SUCCESS(rc))
{
{
if (phMod)
for (; i < cModules; i++)
return rc;
}
}
}
}
return VERR_SYMBOL_NOT_FOUND;
}
/**
* Query a symbol by name, allocating the returned symbol structure.
*
* @returns IPRT status code.
* @retval VERR_SYMBOL_NOT_FOUND if not found.
*
* @param hDbgAs The address space handle.
* @param pszSymbol The symbol name. See RTDbgAsSymbolByName for more.
* @param ppSymbol Where to return the pointer to the allocated
* symbol info. Always set. Free with RTDbgSymbolFree.
* @param phMod Where to return the module handle. Optional.
*/
RTDECL(int) RTDbgAsSymbolByNameA(RTDBGAS hDbgAs, const char *pszSymbol, PRTDBGSYMBOL *ppSymbol, PRTDBGMOD phMod)
{
/*
* Validate input.
*/
/*
* Look for module pattern.
*/
const char *pachModPat = NULL;
if (pszBang)
{
if (!*pszSymbol)
/* Note! Zero length module -> no pattern -> escape for symbol with '!'. */
}
/*
* Iterate the modules, looking for the symbol.
*/
if (!pahModules)
return VERR_NO_TMP_MEMORY;
{
if ( cchModPat == 0
{
if (RT_SUCCESS(rc))
{
{
if (phMod)
for (; i < cModules; i++)
return rc;
}
}
}
}
return VERR_SYMBOL_NOT_FOUND;
}
/**
* Adds a line number to a module in the address space.
*
* @returns IPRT status code. See RTDbgModSymbolAdd for more specific ones.
* @retval VERR_INVALID_HANDLE if hDbgAs is invalid.
* @retval VERR_NOT_FOUND if no module was found at the specified address.
* @retval VERR_NOT_SUPPORTED if the module interpret doesn't support adding
* custom symbols.
*
* @param hDbgAs The address space handle.
* @param pszFile The file name.
* @param uLineNo The line number.
* @param Addr The address of the symbol.
* @param piOrdinal Where to return the line number ordinal on success.
* If the interpreter doesn't do ordinals, this will be
* set to UINT32_MAX. Optional.
*/
RTDECL(int) RTDbgAsLineAdd(RTDBGAS hDbgAs, const char *pszFile, uint32_t uLineNo, RTUINTPTR Addr, uint32_t *piOrdinal)
{
/*
* Validate input and resolve the address.
*/
if (hMod == NIL_RTDBGMOD)
return VERR_NOT_FOUND;
/*
* Forward the call.
*/
return rc;
}
/**
* Query a line number by address.
*
* @returns IPRT status code. See RTDbgModSymbolAddrA for more specific ones.
* @retval VERR_INVALID_HANDLE if hDbgAs is invalid.
* @retval VERR_NOT_FOUND if the address couldn't be mapped to a module.
*
* @param hDbgAs The address space handle.
* @param Addr The address which closest symbol is requested.
* @param poffDisp Where to return the distance between the line
* number and address.
* @param pLine Where to return the line number information.
*/
{
/*
* Validate input and resolve the address.
*/
if (hMod == NIL_RTDBGMOD)
return VERR_NOT_FOUND;
/*
* Forward the call.
*/
if (RT_SUCCESS(rc))
return rc;
}
/**
* Query a line number by address.
*
* @returns IPRT status code. See RTDbgModSymbolAddrA for more specific ones.
* @retval VERR_INVALID_HANDLE if hDbgAs is invalid.
* @retval VERR_NOT_FOUND if the address couldn't be mapped to a module.
*
* @param hDbgAs The address space handle.
* @param Addr The address which closest symbol is requested.
* @param poffDisp Where to return the distance between the line
* number and address.
* @param ppLine Where to return the pointer to the allocated line
* number info. Always set. Free with RTDbgLineFree.
*/
RTDECL(int) RTDbgAsLineByAddrA(RTDBGAS hDbgAs, RTUINTPTR Addr, PRTINTPTR poffDisp, PRTDBGLINE *ppLine)
{
/*
* Validate input and resolve the address.
*/
if (hMod == NIL_RTDBGMOD)
return VERR_NOT_FOUND;
/*
* Forward the call.
*/
if (RT_SUCCESS(rc))
return rc;
}