8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/* $Id$ */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/** @file
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * IPRT - Debug Address Space.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/*
c7814cf6e1240a519cbec0441e033d0e2470ed00vboxsync * Copyright (C) 2009-2012 Oracle Corporation
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * available from http://www.virtualbox.org. This file is free software;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * you can redistribute it and/or modify it under the terms of the GNU
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * General Public License (GPL) as published by the Free Software
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * The contents of this file may alternatively be used under the terms
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * of the Common Development and Distribution License Version 1.0
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * VirtualBox OSE distribution, in which case the provisions of the
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * CDDL are applicable instead of those of the GPL.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * You may elect to license modified versions of this file under the
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * terms and conditions of either the GPL or the CDDL or both.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/*******************************************************************************
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync* Header Files *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync*******************************************************************************/
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync#include <iprt/dbg.h>
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsync#include "internal/iprt.h"
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync#include <iprt/asm.h>
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync#include <iprt/avl.h>
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync#include <iprt/assert.h>
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync#include <iprt/err.h>
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync#include <iprt/mem.h>
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync#include <iprt/param.h>
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync#include <iprt/string.h>
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync#include <iprt/semaphore.h>
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync#include "internal/magics.h"
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/*******************************************************************************
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync* Structures and Typedefs *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync*******************************************************************************/
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/** Pointer to a module table entry. */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsynctypedef struct RTDBGASMOD *PRTDBGASMOD;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/** Pointer to an address space mapping node. */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsynctypedef struct RTDBGASMAP *PRTDBGASMAP;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/** Pointer to a name head. */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsynctypedef struct RTDBGASNAME *PRTDBGASNAME;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/**
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Module entry.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsynctypedef struct RTDBGASMOD
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync{
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /** Node core, the module handle is the key. */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync AVLPVNODECORE Core;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /** Pointer to the first mapping of the module or a segment within it. */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync PRTDBGASMAP pMapHead;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /** Pointer to the next module with an identical name. */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync PRTDBGASMOD pNextName;
8df047381fb076540a191d281498b66ba9182dbdvboxsync /** The index into RTDBGASINT::papModules. */
8df047381fb076540a191d281498b66ba9182dbdvboxsync uint32_t iOrdinal;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync} RTDBGASMOD;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/**
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * An address space mapping, either of a full module or a segment.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsynctypedef struct RTDBGASMAP
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync{
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /** The AVL node core. Contains the address range. */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync AVLRUINTPTRNODECORE Core;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /** Pointer to the next mapping of the module. */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync PRTDBGASMAP pNext;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /** Pointer to the module. */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync PRTDBGASMOD pMod;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /** Which segment in the module.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * This is NIL_RTDBGSEGIDX when the entire module is mapped. */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTDBGSEGIDX iSeg;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync} RTDBGASMAP;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/**
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Name in the address space.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsynctypedef struct RTDBGASNAME
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync{
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /** The string space node core.*/
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTSTRSPACECORE StrCore;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /** The list of nodes */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync PRTDBGASMOD pHead;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync} RTDBGASNAME;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/**
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Debug address space instance.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsynctypedef struct RTDBGASINT
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync{
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /** Magic value (RTDBGAS_MAGIC). */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync uint32_t u32Magic;
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync /** The number of reference to this address space. */
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync uint32_t volatile cRefs;
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync /** Handle of the read-write lock. */
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync RTSEMRW hLock;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /** Number of modules in the module address space. */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync uint32_t cModules;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /** Pointer to the module table.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * The valid array length is given by cModules. */
8df047381fb076540a191d281498b66ba9182dbdvboxsync PRTDBGASMOD *papModules;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /** AVL tree translating module handles to module entries. */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync AVLPVTREE ModTree;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /** AVL tree mapping addresses to modules. */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync AVLRUINTPTRTREE MapTree;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /** Names of the modules in the name space. */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTSTRSPACE NameSpace;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /** The first address the AS. */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTUINTPTR FirstAddr;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /** The last address in the AS. */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTUINTPTR LastAddr;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /** The name of the address space. (variable length) */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync char szName[1];
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync} RTDBGASINT;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/** Pointer to an a debug address space instance. */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsynctypedef RTDBGASINT *PRTDBGASINT;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/*******************************************************************************
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync* Defined Constants And Macros *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync*******************************************************************************/
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync/** Validates an address space handle and returns rc if not valid. */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync#define RTDBGAS_VALID_RETURN_RC(pDbgAs, rc) \
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync do { \
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync AssertPtrReturn((pDbgAs), (rc)); \
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync AssertReturn((pDbgAs)->u32Magic == RTDBGAS_MAGIC, (rc)); \
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync AssertReturn((pDbgAs)->cRefs > 0, (rc)); \
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync } while (0)
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync/** Locks the address space for reading. */
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync#define RTDBGAS_LOCK_READ(pDbgAs) \
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync do { \
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync int rcLock = RTSemRWRequestRead((pDbgAs)->hLock, RT_INDEFINITE_WAIT); \
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync AssertRC(rcLock); \
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync } while (0)
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync/** Unlocks the address space after reading. */
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync#define RTDBGAS_UNLOCK_READ(pDbgAs) \
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync do { \
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync int rcLock = RTSemRWReleaseRead((pDbgAs)->hLock); \
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync AssertRC(rcLock); \
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync } while (0)
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync/** Locks the address space for writing. */
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync#define RTDBGAS_LOCK_WRITE(pDbgAs) \
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync do { \
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync int rcLock = RTSemRWRequestWrite((pDbgAs)->hLock, RT_INDEFINITE_WAIT); \
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync AssertRC(rcLock); \
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync } while (0)
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync/** Unlocks the address space after writing. */
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync#define RTDBGAS_UNLOCK_WRITE(pDbgAs) \
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync do { \
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync int rcLock = RTSemRWReleaseWrite((pDbgAs)->hLock); \
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync AssertRC(rcLock); \
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync } while (0)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/*******************************************************************************
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync* Internal Functions *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync*******************************************************************************/
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsyncstatic void rtDbgAsModuleUnlinkMod(PRTDBGASINT pDbgAs, PRTDBGASMOD pMod);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsyncstatic void rtDbgAsModuleUnlinkByMap(PRTDBGASINT pDbgAs, PRTDBGASMAP pMap);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/**
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Creates an empty address space.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @returns IPRT status code.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param phDbgAs Where to store the address space handle on success.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param FirstAddr The first address in the address space.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param LastAddr The last address in the address space.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param pszName The name of the address space.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsyncRTDECL(int) RTDbgAsCreate(PRTDBGAS phDbgAs, RTUINTPTR FirstAddr, RTUINTPTR LastAddr, const char *pszName)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync{
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Input validation.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync AssertPtrReturn(phDbgAs, VERR_INVALID_POINTER);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync AssertPtrReturn(pszName, VERR_INVALID_POINTER);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync AssertReturn(FirstAddr < LastAddr, VERR_INVALID_PARAMETER);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Allocate memory for the instance data.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync size_t cchName = strlen(pszName);
01d9248e0a8f571bad985077a05a12f604181c9fvboxsync PRTDBGASINT pDbgAs = (PRTDBGASINT)RTMemAllocVar(RT_OFFSETOF(RTDBGASINT, szName[cchName + 1]));
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync if (!pDbgAs)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync return VERR_NO_MEMORY;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync /* initialize it. */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync pDbgAs->u32Magic = RTDBGAS_MAGIC;
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync pDbgAs->cRefs = 1;
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync pDbgAs->hLock = NIL_RTSEMRW;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync pDbgAs->cModules = 0;
8df047381fb076540a191d281498b66ba9182dbdvboxsync pDbgAs->papModules = NULL;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync pDbgAs->ModTree = NULL;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync pDbgAs->MapTree = NULL;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync pDbgAs->NameSpace = NULL;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync pDbgAs->FirstAddr = FirstAddr;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync pDbgAs->LastAddr = LastAddr;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync memcpy(pDbgAs->szName, pszName, cchName + 1);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync int rc = RTSemRWCreate(&pDbgAs->hLock);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync if (RT_SUCCESS(rc))
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync {
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync *phDbgAs = pDbgAs;
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync return VINF_SUCCESS;
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync }
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync pDbgAs->u32Magic = 0;
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync RTMemFree(pDbgAs);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync return rc;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync}
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsyncRT_EXPORT_SYMBOL(RTDbgAsCreate);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/**
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Variant of RTDbgAsCreate that takes a name format string.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @returns IPRT status code.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param phDbgAs Where to store the address space handle on success.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param FirstAddr The first address in the address space.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param LastAddr The last address in the address space.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param pszNameFmt The name format of the address space.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param va Format arguments.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsyncRTDECL(int) RTDbgAsCreateV(PRTDBGAS phDbgAs, RTUINTPTR FirstAddr, RTUINTPTR LastAddr, const char *pszNameFmt, va_list va)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync{
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync AssertPtrReturn(pszNameFmt, VERR_INVALID_POINTER);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync char *pszName;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTStrAPrintfV(&pszName, pszNameFmt, va);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync if (!pszName)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync return VERR_NO_MEMORY;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync int rc = RTDbgAsCreate(phDbgAs, FirstAddr, LastAddr, pszName);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTStrFree(pszName);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync return rc;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync}
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsyncRT_EXPORT_SYMBOL(RTDbgAsCreateV);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/**
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Variant of RTDbgAsCreate that takes a name format string.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @returns IPRT status code.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param phDbgAs Where to store the address space handle on success.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param FirstAddr The first address in the address space.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param LastAddr The last address in the address space.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param pszNameFmt The name format of the address space.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param ... Format arguments.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsyncRTDECL(int) RTDbgAsCreateF(PRTDBGAS phDbgAs, RTUINTPTR FirstAddr, RTUINTPTR LastAddr, const char *pszNameFmt, ...)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync{
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync va_list va;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync va_start(va, pszNameFmt);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync int rc = RTDbgAsCreateV(phDbgAs, FirstAddr, LastAddr, pszNameFmt, va);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync va_end(va);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync return rc;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync}
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsyncRT_EXPORT_SYMBOL(RTDbgAsCreateF);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/**
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Callback used by RTDbgAsDestroy to free all mapping nodes.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @returns 0
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param pNode The map node.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param pvUser NULL.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsyncstatic DECLCALLBACK(int) rtDbgAsDestroyMapCallback(PAVLRUINTPTRNODECORE pNode, void *pvUser)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync{
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTMemFree(pNode);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync NOREF(pvUser);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync return 0;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync}
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/**
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Callback used by RTDbgAsDestroy to free all name space nodes.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @returns 0
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param pStr The name node.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param pvUser NULL.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsyncstatic DECLCALLBACK(int) rtDbgAsDestroyNameCallback(PRTSTRSPACECORE pStr, void *pvUser)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync{
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTMemFree(pStr);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync NOREF(pvUser);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync return 0;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync}
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/**
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Destroys the address space.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * This means unlinking all the modules it currently contains, potentially
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * causing some or all of them to be destroyed as they are managed by
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * reference counting.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * @param pDbgAs The address space instance to be destroyed.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsyncstatic void rtDbgAsDestroy(PRTDBGASINT pDbgAs)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync{
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Mark the address space invalid and release all the modules.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync ASMAtomicWriteU32(&pDbgAs->u32Magic, ~RTDBGAS_MAGIC);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTAvlrUIntPtrDestroy(&pDbgAs->MapTree, rtDbgAsDestroyMapCallback, NULL);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTStrSpaceDestroy(&pDbgAs->NameSpace, rtDbgAsDestroyNameCallback, NULL);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync uint32_t i = pDbgAs->cModules;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync while (i-- > 0)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync {
8df047381fb076540a191d281498b66ba9182dbdvboxsync PRTDBGASMOD pMod = pDbgAs->papModules[i];
8df047381fb076540a191d281498b66ba9182dbdvboxsync AssertPtr(pMod);
8df047381fb076540a191d281498b66ba9182dbdvboxsync if (VALID_PTR(pMod))
8df047381fb076540a191d281498b66ba9182dbdvboxsync {
8df047381fb076540a191d281498b66ba9182dbdvboxsync Assert(pMod->iOrdinal == i);
8df047381fb076540a191d281498b66ba9182dbdvboxsync RTDbgModRelease((RTDBGMOD)pMod->Core.Key);
8df047381fb076540a191d281498b66ba9182dbdvboxsync pMod->Core.Key = NIL_RTDBGMOD;
8df047381fb076540a191d281498b66ba9182dbdvboxsync pMod->iOrdinal = UINT32_MAX;
8df047381fb076540a191d281498b66ba9182dbdvboxsync RTMemFree(pMod);
8df047381fb076540a191d281498b66ba9182dbdvboxsync }
8df047381fb076540a191d281498b66ba9182dbdvboxsync pDbgAs->papModules[i] = NULL;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync }
8df047381fb076540a191d281498b66ba9182dbdvboxsync RTMemFree(pDbgAs->papModules);
8df047381fb076540a191d281498b66ba9182dbdvboxsync pDbgAs->papModules = NULL;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTMemFree(pDbgAs);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync}
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync/**
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync * Retains another reference to the address space.
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync *
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * @returns New reference count, UINT32_MAX on invalid handle (asserted).
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync *
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * @param hDbgAs The address space handle.
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync *
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * @remarks Will not take any locks.
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync */
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsyncRTDECL(uint32_t) RTDbgAsRetain(RTDBGAS hDbgAs)
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync{
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync PRTDBGASINT pDbgAs = hDbgAs;
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, UINT32_MAX);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync return ASMAtomicIncU32(&pDbgAs->cRefs);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync}
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsyncRT_EXPORT_SYMBOL(RTDbgAsRetain);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync/**
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * Release a reference to the address space.
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync *
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * When the reference count reaches zero, the address space is destroyed.
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * That means unlinking all the modules it currently contains, potentially
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * causing some or all of them to be destroyed as they are managed by
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * reference counting.
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync *
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * @returns New reference count, UINT32_MAX on invalid handle (asserted).
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync *
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * @param hDbgAs The address space handle. The NIL handle is quietly
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * ignored and 0 is returned.
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync *
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * @remarks Will not take any locks.
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync */
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsyncRTDECL(uint32_t) RTDbgAsRelease(RTDBGAS hDbgAs)
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync{
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync if (hDbgAs == NIL_RTDBGAS)
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync return 0;
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync PRTDBGASINT pDbgAs = hDbgAs;
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, UINT32_MAX);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync uint32_t cRefs = ASMAtomicDecU32(&pDbgAs->cRefs);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync if (!cRefs)
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync rtDbgAsDestroy(pDbgAs);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync return cRefs;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync}
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsyncRT_EXPORT_SYMBOL(RTDbgAsRelease);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
31771163041e3661403a806eb3382d2a165c003bvboxsyncRTDECL(int) RTDbgAsLockExcl(RTDBGAS hDbgAs)
31771163041e3661403a806eb3382d2a165c003bvboxsync{
31771163041e3661403a806eb3382d2a165c003bvboxsync PRTDBGASINT pDbgAs = hDbgAs;
31771163041e3661403a806eb3382d2a165c003bvboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, VERR_INVALID_HANDLE);
31771163041e3661403a806eb3382d2a165c003bvboxsync RTDBGAS_LOCK_WRITE(pDbgAs);
31771163041e3661403a806eb3382d2a165c003bvboxsync return VINF_SUCCESS;
31771163041e3661403a806eb3382d2a165c003bvboxsync}
31771163041e3661403a806eb3382d2a165c003bvboxsyncRT_EXPORT_SYMBOL(RTDbgAsLockExcl);
31771163041e3661403a806eb3382d2a165c003bvboxsync
31771163041e3661403a806eb3382d2a165c003bvboxsync
31771163041e3661403a806eb3382d2a165c003bvboxsyncRTDECL(int) RTDbgAsUnlockExcl(RTDBGAS hDbgAs)
31771163041e3661403a806eb3382d2a165c003bvboxsync{
31771163041e3661403a806eb3382d2a165c003bvboxsync PRTDBGASINT pDbgAs = hDbgAs;
31771163041e3661403a806eb3382d2a165c003bvboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, VERR_INVALID_HANDLE);
31771163041e3661403a806eb3382d2a165c003bvboxsync RTDBGAS_UNLOCK_WRITE(pDbgAs);
31771163041e3661403a806eb3382d2a165c003bvboxsync return VINF_SUCCESS;
31771163041e3661403a806eb3382d2a165c003bvboxsync}
31771163041e3661403a806eb3382d2a165c003bvboxsyncRT_EXPORT_SYMBOL(RTDbgAsUnlockExcl);
31771163041e3661403a806eb3382d2a165c003bvboxsync
31771163041e3661403a806eb3382d2a165c003bvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/**
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Gets the name of an address space.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @returns read only address space name.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * NULL if hDbgAs is invalid.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param hDbgAs The address space handle.
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync *
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * @remarks Will not take any locks.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsyncRTDECL(const char *) RTDbgAsName(RTDBGAS hDbgAs)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync{
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync PRTDBGASINT pDbgAs = hDbgAs;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, NULL);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync return pDbgAs->szName;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync}
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsyncRT_EXPORT_SYMBOL(RTDbgAsName);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/**
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Gets the first address in an address space.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @returns The address.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * 0 if hDbgAs is invalid.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param hDbgAs The address space handle.
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync *
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * @remarks Will not take any locks.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsyncRTDECL(RTUINTPTR) RTDbgAsFirstAddr(RTDBGAS hDbgAs)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync{
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync PRTDBGASINT pDbgAs = hDbgAs;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, 0);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync return pDbgAs->FirstAddr;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync}
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsyncRT_EXPORT_SYMBOL(RTDbgAsFirstAddr);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/**
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Gets the last address in an address space.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @returns The address.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * 0 if hDbgAs is invalid.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param hDbgAs The address space handle.
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync *
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * @remarks Will not take any locks.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsyncRTDECL(RTUINTPTR) RTDbgAsLastAddr(RTDBGAS hDbgAs)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync{
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync PRTDBGASINT pDbgAs = hDbgAs;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, 0);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync return pDbgAs->LastAddr;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync}
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsyncRT_EXPORT_SYMBOL(RTDbgAsLastAddr);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/**
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Gets the number of modules in the address space.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * This can be used together with RTDbgAsModuleByIndex
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * to enumerate the modules.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @returns The number of modules.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param hDbgAs The address space handle.
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync *
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * @remarks Will not take any locks.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsyncRTDECL(uint32_t) RTDbgAsModuleCount(RTDBGAS hDbgAs)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync{
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync PRTDBGASINT pDbgAs = hDbgAs;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, 0);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync return pDbgAs->cModules;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync}
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsyncRT_EXPORT_SYMBOL(RTDbgAsModuleCount);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/**
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Common worker for RTDbgAsModuleLink and RTDbgAsModuleLinkSeg.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @returns IPRT status.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param pDbgAs Pointer to the address space instance data.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param hDbgMod The module to link.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param iSeg The segment to link or NIL if all.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param Addr The address we're linking it at.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param cb The size of what we're linking.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param pszName The name of the module.
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * @param fFlags See RTDBGASLINK_FLAGS_*.
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync *
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * @remarks The caller must have locked the address space for writing.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsyncint rtDbgAsModuleLinkCommon(PRTDBGASINT pDbgAs, RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg,
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync RTUINTPTR Addr, RTUINTPTR cb, const char *pszName, uint32_t fFlags)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync{
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Check that the requested space is undisputed.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync for (;;)
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync {
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync PRTDBGASMAP pAdjMod = (PRTDBGASMAP)RTAvlrUIntPtrGetBestFit(&pDbgAs->MapTree, Addr, false /* fAbove */);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync if ( pAdjMod
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync && pAdjMod->Core.KeyLast >= Addr)
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync {
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync if (!(fFlags & RTDBGASLINK_FLAGS_REPLACE))
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync return VERR_ADDRESS_CONFLICT;
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync rtDbgAsModuleUnlinkByMap(pDbgAs, pAdjMod);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync continue;
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync }
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync pAdjMod = (PRTDBGASMAP)RTAvlrUIntPtrGetBestFit(&pDbgAs->MapTree, Addr, true /* fAbove */);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync if ( pAdjMod
77b92045ecae7978726dd23cb3d5de4676aec1c9vboxsync && pAdjMod->Core.Key <= Addr + cb - 1)
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync {
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync if (!(fFlags & RTDBGASLINK_FLAGS_REPLACE))
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync return VERR_ADDRESS_CONFLICT;
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync rtDbgAsModuleUnlinkByMap(pDbgAs, pAdjMod);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync continue;
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync }
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync break;
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync }
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * First, create or find the module table entry.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync PRTDBGASMOD pMod = (PRTDBGASMOD)RTAvlPVGet(&pDbgAs->ModTree, hDbgMod);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync if (!pMod)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync {
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Ok, we need a new entry. Grow the table if necessary.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync if (!(pDbgAs->cModules % 32))
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync {
8df047381fb076540a191d281498b66ba9182dbdvboxsync void *pvNew = RTMemRealloc(pDbgAs->papModules, sizeof(pDbgAs->papModules[0]) * (pDbgAs->cModules + 32));
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync if (!pvNew)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync return VERR_NO_MEMORY;
8df047381fb076540a191d281498b66ba9182dbdvboxsync pDbgAs->papModules = (PRTDBGASMOD *)pvNew;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync }
8df047381fb076540a191d281498b66ba9182dbdvboxsync pMod = (PRTDBGASMOD)RTMemAlloc(sizeof(*pMod));
8df047381fb076540a191d281498b66ba9182dbdvboxsync if (!pMod)
8df047381fb076540a191d281498b66ba9182dbdvboxsync return VERR_NO_MEMORY;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync pMod->Core.Key = hDbgMod;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync pMod->pMapHead = NULL;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync pMod->pNextName = NULL;
8df047381fb076540a191d281498b66ba9182dbdvboxsync if (RT_UNLIKELY(!RTAvlPVInsert(&pDbgAs->ModTree, &pMod->Core)))
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync {
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync AssertFailed();
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync pDbgAs->cModules--;
8df047381fb076540a191d281498b66ba9182dbdvboxsync RTMemFree(pMod);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync return VERR_INTERNAL_ERROR;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync }
8df047381fb076540a191d281498b66ba9182dbdvboxsync pMod->iOrdinal = pDbgAs->cModules;
8df047381fb076540a191d281498b66ba9182dbdvboxsync pDbgAs->papModules[pDbgAs->cModules] = pMod;
8df047381fb076540a191d281498b66ba9182dbdvboxsync pDbgAs->cModules++;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTDbgModRetain(hDbgMod);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Add it to the name space.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync PRTDBGASNAME pName = (PRTDBGASNAME)RTStrSpaceGet(&pDbgAs->NameSpace, pszName);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync if (!pName)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync {
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync size_t cchName = strlen(pszName);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync pName = (PRTDBGASNAME)RTMemAlloc(sizeof(*pName) + cchName + 1);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync if (!pName)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync {
8df047381fb076540a191d281498b66ba9182dbdvboxsync RTDbgModRelease(hDbgMod);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync pDbgAs->cModules--;
77b92045ecae7978726dd23cb3d5de4676aec1c9vboxsync RTAvlPVRemove(&pDbgAs->ModTree, hDbgMod);
8df047381fb076540a191d281498b66ba9182dbdvboxsync RTMemFree(pMod);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync return VERR_NO_MEMORY;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync }
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync pName->StrCore.cchString = cchName;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync pName->StrCore.pszString = (char *)memcpy(pName + 1, pszName, cchName + 1);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync pName->pHead = pMod;
77b92045ecae7978726dd23cb3d5de4676aec1c9vboxsync if (!RTStrSpaceInsert(&pDbgAs->NameSpace, &pName->StrCore))
77b92045ecae7978726dd23cb3d5de4676aec1c9vboxsync AssertFailed();
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync }
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync else
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync {
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /* quick, but unfair. */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync pMod->pNextName = pName->pHead;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync pName->pHead = pMod;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync }
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync }
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Create a mapping node.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync int rc;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync PRTDBGASMAP pMap = (PRTDBGASMAP)RTMemAlloc(sizeof(*pMap));
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync if (pMap)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync {
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync pMap->Core.Key = Addr;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync pMap->Core.KeyLast = Addr + cb - 1;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync pMap->pMod = pMod;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync pMap->iSeg = iSeg;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync if (RTAvlrUIntPtrInsert(&pDbgAs->MapTree, &pMap->Core))
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync {
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync PRTDBGASMAP *pp = &pMod->pMapHead;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync while (*pp && (*pp)->Core.Key < Addr)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync pp = &(*pp)->pNext;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync pMap->pNext = *pp;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *pp = pMap;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync return VINF_SUCCESS;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync }
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync AssertFailed();
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTMemFree(pMap);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync rc = VERR_ADDRESS_CONFLICT;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync }
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync else
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync rc = VERR_NO_MEMORY;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Unlink the module if this was the only mapping.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync if (!pMod->pMapHead)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync rtDbgAsModuleUnlinkMod(pDbgAs, pMod);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync return rc;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync}
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/**
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Links a module into the address space at the give address.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * The size of the mapping is determined using RTDbgModImageSize().
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @returns IPRT status code.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @retval VERR_OUT_OF_RANGE if the specified address will put the module
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * outside the address space.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @retval VERR_ADDRESS_CONFLICT if the mapping clashes with existing mappings.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param hDbgAs The address space handle.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param hDbgMod The module handle of the module to be linked in.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param ImageAddr The address to link the module at.
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * @param fFlags See RTDBGASLINK_FLAGS_*.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsyncRTDECL(int) RTDbgAsModuleLink(RTDBGAS hDbgAs, RTDBGMOD hDbgMod, RTUINTPTR ImageAddr, uint32_t fFlags)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync{
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Validate input.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync PRTDBGASINT pDbgAs = hDbgAs;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, VERR_INVALID_HANDLE);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync const char *pszName = RTDbgModName(hDbgMod);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync if (!pszName)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync return VERR_INVALID_HANDLE;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTUINTPTR cb = RTDbgModImageSize(hDbgMod);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync if (!cb)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync return VERR_OUT_OF_RANGE;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync if ( ImageAddr < pDbgAs->FirstAddr
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync || ImageAddr > pDbgAs->LastAddr
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync || ImageAddr + cb - 1 < pDbgAs->FirstAddr
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync || ImageAddr + cb - 1 > pDbgAs->LastAddr
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync || ImageAddr + cb - 1 < ImageAddr)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync return VERR_OUT_OF_RANGE;
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync AssertReturn(!(fFlags & ~RTDBGASLINK_FLAGS_VALID_MASK), VERR_INVALID_PARAMETER);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Invoke worker common with RTDbgAsModuleLinkSeg.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync RTDBGAS_LOCK_WRITE(pDbgAs);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync int rc = rtDbgAsModuleLinkCommon(pDbgAs, hDbgMod, NIL_RTDBGSEGIDX, ImageAddr, cb, pszName, fFlags);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync RTDBGAS_UNLOCK_WRITE(pDbgAs);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync return rc;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync}
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsyncRT_EXPORT_SYMBOL(RTDbgAsModuleLink);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/**
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Links a segment into the address space at the give address.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * The size of the mapping is determined using RTDbgModSegmentSize().
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @returns IPRT status code.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @retval VERR_OUT_OF_RANGE if the specified address will put the module
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * outside the address space.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @retval VERR_ADDRESS_CONFLICT if the mapping clashes with existing mappings.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param hDbgAs The address space handle.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param hDbgMod The module handle.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param iSeg The segment number (0-based) of the segment to be
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * linked in.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param SegAddr The address to link the segment at.
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * @param fFlags See RTDBGASLINK_FLAGS_*.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsyncRTDECL(int) RTDbgAsModuleLinkSeg(RTDBGAS hDbgAs, RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg, RTUINTPTR SegAddr, uint32_t fFlags)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync{
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Validate input.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync PRTDBGASINT pDbgAs = hDbgAs;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, VERR_INVALID_HANDLE);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync const char *pszName = RTDbgModName(hDbgMod);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync if (!pszName)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync return VERR_INVALID_HANDLE;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTUINTPTR cb = RTDbgModSegmentSize(hDbgMod, iSeg);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync if (!cb)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync return VERR_OUT_OF_RANGE;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync if ( SegAddr < pDbgAs->FirstAddr
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync || SegAddr > pDbgAs->LastAddr
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync || SegAddr + cb - 1 < pDbgAs->FirstAddr
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync || SegAddr + cb - 1 > pDbgAs->LastAddr
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync || SegAddr + cb - 1 < SegAddr)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync return VERR_OUT_OF_RANGE;
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync AssertReturn(!(fFlags & ~RTDBGASLINK_FLAGS_VALID_MASK), VERR_INVALID_PARAMETER);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Invoke worker common with RTDbgAsModuleLinkSeg.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync RTDBGAS_LOCK_WRITE(pDbgAs);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync int rc = rtDbgAsModuleLinkCommon(pDbgAs, hDbgMod, iSeg, SegAddr, cb, pszName, fFlags);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync RTDBGAS_UNLOCK_WRITE(pDbgAs);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync return rc;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync}
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsyncRT_EXPORT_SYMBOL(RTDbgAsModuleLinkSeg);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/**
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Worker for RTDbgAsModuleUnlink, RTDbgAsModuleUnlinkByAddr and rtDbgAsModuleLinkCommon.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param pDbgAs Pointer to the address space instance data.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param pMod The module to unlink.
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync *
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * @remarks The caller must have locked the address space for writing.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsyncstatic void rtDbgAsModuleUnlinkMod(PRTDBGASINT pDbgAs, PRTDBGASMOD pMod)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync{
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync Assert(!pMod->pMapHead);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Unlink it from the name.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
77b92045ecae7978726dd23cb3d5de4676aec1c9vboxsync const char *pszName = RTDbgModName((RTDBGMOD)pMod->Core.Key);
77b92045ecae7978726dd23cb3d5de4676aec1c9vboxsync PRTDBGASNAME pName = (PRTDBGASNAME)RTStrSpaceGet(&pDbgAs->NameSpace, pszName);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync AssertReturnVoid(pName);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync if (pName->pHead == pMod)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync pName->pHead = pMod->pNextName;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync else
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync for (PRTDBGASMOD pCur = pName->pHead; pCur; pCur = pCur->pNextName)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync if (pCur->pNextName == pMod)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync {
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync pCur->pNextName = pMod->pNextName;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync break;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync }
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync pMod->pNextName = NULL;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Free the name if this was the last reference to it.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync if (!pName->pHead)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync {
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync pName = (PRTDBGASNAME)RTStrSpaceRemove(&pDbgAs->NameSpace, pName->StrCore.pszString);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync Assert(pName);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTMemFree(pName);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync }
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Remove it from the module handle tree.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync PAVLPVNODECORE pNode = RTAvlPVRemove(&pDbgAs->ModTree, pMod->Core.Key);
2f7d372a31fd0f5515c2d307db549db16dd443f0vboxsync Assert(pNode == &pMod->Core); NOREF(pNode);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Remove it from the module table by replacing it by the last entry.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync pDbgAs->cModules--;
8df047381fb076540a191d281498b66ba9182dbdvboxsync uint32_t iMod = pMod->iOrdinal;
8df047381fb076540a191d281498b66ba9182dbdvboxsync Assert(iMod <= pDbgAs->cModules);
8df047381fb076540a191d281498b66ba9182dbdvboxsync if (iMod != pDbgAs->cModules)
77b92045ecae7978726dd23cb3d5de4676aec1c9vboxsync {
8df047381fb076540a191d281498b66ba9182dbdvboxsync PRTDBGASMOD pTailMod = pDbgAs->papModules[pDbgAs->cModules];
8df047381fb076540a191d281498b66ba9182dbdvboxsync pTailMod->iOrdinal = iMod;
8df047381fb076540a191d281498b66ba9182dbdvboxsync pDbgAs->papModules[iMod] = pTailMod;
77b92045ecae7978726dd23cb3d5de4676aec1c9vboxsync }
8df047381fb076540a191d281498b66ba9182dbdvboxsync pMod->iOrdinal = UINT32_MAX;
8df047381fb076540a191d281498b66ba9182dbdvboxsync
8df047381fb076540a191d281498b66ba9182dbdvboxsync /*
8df047381fb076540a191d281498b66ba9182dbdvboxsync * Free it.
8df047381fb076540a191d281498b66ba9182dbdvboxsync */
8df047381fb076540a191d281498b66ba9182dbdvboxsync RTMemFree(pMod);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync}
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/**
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Worker for RTDbgAsModuleUnlink and RTDbgAsModuleUnlinkByAddr.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param pDbgAs Pointer to the address space instance data.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param pMap The map to unlink and free.
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync *
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * @remarks The caller must have locked the address space for writing.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsyncstatic void rtDbgAsModuleUnlinkMap(PRTDBGASINT pDbgAs, PRTDBGASMAP pMap)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync{
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /* remove from the tree */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync PAVLRUINTPTRNODECORE pNode = RTAvlrUIntPtrRemove(&pDbgAs->MapTree, pMap->Core.Key);
2f7d372a31fd0f5515c2d307db549db16dd443f0vboxsync Assert(pNode == &pMap->Core); NOREF(pNode);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /* unlink */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync PRTDBGASMOD pMod = pMap->pMod;
8df047381fb076540a191d281498b66ba9182dbdvboxsync if (pMod->pMapHead == pMap)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync pMod->pMapHead = pMap->pNext;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync else
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync {
77b92045ecae7978726dd23cb3d5de4676aec1c9vboxsync bool fFound = false;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync for (PRTDBGASMAP pCur = pMod->pMapHead; pCur; pCur = pCur->pNext)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync if (pCur->pNext == pMap)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync {
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync pCur->pNext = pMap->pNext;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync fFound = true;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync break;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync }
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync Assert(fFound);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync }
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /* free it */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync pMap->Core.Key = pMap->Core.KeyLast = 0;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync pMap->pNext = NULL;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync pMap->pMod = NULL;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTMemFree(pMap);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync}
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync/**
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * Worker for RTDbgAsModuleUnlinkByAddr and rtDbgAsModuleLinkCommon that
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * unlinks a single mapping and releases the module if it's the last one.
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync *
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * @param pDbgAs The address space instance.
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * @param pMap The mapping to unlink.
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync *
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * @remarks The caller must have locked the address space for writing.
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync */
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsyncstatic void rtDbgAsModuleUnlinkByMap(PRTDBGASINT pDbgAs, PRTDBGASMAP pMap)
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync{
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync /*
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * Unlink it from the address space.
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * Unlink the module as well if it's the last mapping it has.
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync */
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync PRTDBGASMOD pMod = pMap->pMod;
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync rtDbgAsModuleUnlinkMap(pDbgAs, pMap);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync if (!pMod->pMapHead)
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync rtDbgAsModuleUnlinkMod(pDbgAs, pMod);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync}
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/**
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Unlinks all the mappings of a module from the address space.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @returns IPRT status code.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @retval VERR_NOT_FOUND if the module wasn't found.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param hDbgAs The address space handle.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param hDbgMod The module handle of the module to be unlinked.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsyncRTDECL(int) RTDbgAsModuleUnlink(RTDBGAS hDbgAs, RTDBGMOD hDbgMod)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync{
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Validate input.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync PRTDBGASINT pDbgAs = hDbgAs;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, VERR_INVALID_HANDLE);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync if (hDbgMod == NIL_RTDBGMOD)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync return VINF_SUCCESS;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync RTDBGAS_LOCK_WRITE(pDbgAs);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync PRTDBGASMOD pMod = (PRTDBGASMOD)RTAvlPVGet(&pDbgAs->ModTree, hDbgMod);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync if (!pMod)
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync {
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync RTDBGAS_UNLOCK_WRITE(pDbgAs);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync return VERR_NOT_FOUND;
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync }
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * Unmap all everything and release the module.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync while (pMod->pMapHead)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync rtDbgAsModuleUnlinkMap(pDbgAs, pMod->pMapHead);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync rtDbgAsModuleUnlinkMod(pDbgAs, pMod);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync RTDBGAS_UNLOCK_WRITE(pDbgAs);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync return VINF_SUCCESS;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync}
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsyncRT_EXPORT_SYMBOL(RTDbgAsModuleUnlink);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/**
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Unlinks the mapping at the specified address.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @returns IPRT status code.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @retval VERR_NOT_FOUND if no module or segment is mapped at that address.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param hDbgAs The address space handle.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param Addr The address within the mapping to be unlinked.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsyncRTDECL(int) RTDbgAsModuleUnlinkByAddr(RTDBGAS hDbgAs, RTUINTPTR Addr)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync{
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Validate input.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync PRTDBGASINT pDbgAs = hDbgAs;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, VERR_INVALID_HANDLE);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync RTDBGAS_LOCK_WRITE(pDbgAs);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync PRTDBGASMAP pMap = (PRTDBGASMAP)RTAvlrUIntPtrRangeGet(&pDbgAs->MapTree, Addr);
8e36e887209111a8f332e4fee3d0c93caa60f3f0vboxsync if (!pMap)
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync {
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync RTDBGAS_UNLOCK_WRITE(pDbgAs);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync return VERR_NOT_FOUND;
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync }
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * Hand it to
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync rtDbgAsModuleUnlinkByMap(pDbgAs, pMap);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync RTDBGAS_UNLOCK_WRITE(pDbgAs);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync return VINF_SUCCESS;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync}
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsyncRT_EXPORT_SYMBOL(RTDbgAsModuleUnlinkByAddr);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/**
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Get a the handle of a module in the address space by is index.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @returns A retained handle to the specified module. The caller must release
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * the returned reference.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * NIL_RTDBGMOD if invalid index or handle.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param hDbgAs The address space handle.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param iModule The index of the module to get.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @remarks The module indexes may change after calls to RTDbgAsModuleLink,
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * RTDbgAsModuleLinkSeg, RTDbgAsModuleUnlink and
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * RTDbgAsModuleUnlinkByAddr.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsyncRTDECL(RTDBGMOD) RTDbgAsModuleByIndex(RTDBGAS hDbgAs, uint32_t iModule)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync{
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Validate input.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync PRTDBGASINT pDbgAs = hDbgAs;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, NIL_RTDBGMOD);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync RTDBGAS_LOCK_READ(pDbgAs);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync if (iModule >= pDbgAs->cModules)
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync {
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync RTDBGAS_UNLOCK_READ(pDbgAs);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync return NIL_RTDBGMOD;
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync }
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Get, retain and return it.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8df047381fb076540a191d281498b66ba9182dbdvboxsync RTDBGMOD hMod = (RTDBGMOD)pDbgAs->papModules[iModule]->Core.Key;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTDbgModRetain(hMod);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync RTDBGAS_UNLOCK_READ(pDbgAs);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync return hMod;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync}
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsyncRT_EXPORT_SYMBOL(RTDbgAsModuleByIndex);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/**
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Queries mapping module information by handle.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @returns IPRT status code.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @retval VERR_NOT_FOUND if no mapping was found at the specified address.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param hDbgAs The address space handle.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param Addr Address within the mapping of the module or segment.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param phMod Where to the return the retained module handle.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Optional.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param pAddr Where to return the base address of the mapping.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Optional.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param piSeg Where to return the segment index. This is set to
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * NIL if the entire module is mapped as a single
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * mapping. Optional.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsyncRTDECL(int) RTDbgAsModuleByAddr(RTDBGAS hDbgAs, RTUINTPTR Addr, PRTDBGMOD phMod, PRTUINTPTR pAddr, PRTDBGSEGIDX piSeg)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync{
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Validate input.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync PRTDBGASINT pDbgAs = hDbgAs;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, VERR_INVALID_HANDLE);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync RTDBGAS_LOCK_READ(pDbgAs);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync PRTDBGASMAP pMap = (PRTDBGASMAP)RTAvlrUIntPtrRangeGet(&pDbgAs->MapTree, Addr);
f205dfd56d15e6f85ae9f6418b93adea1a00aaccvboxsync if (!pMap)
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync {
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync RTDBGAS_UNLOCK_READ(pDbgAs);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync return VERR_NOT_FOUND;
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync }
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Set up the return values.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync if (phMod)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync {
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTDBGMOD hMod = (RTDBGMOD)pMap->pMod->Core.Key;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTDbgModRetain(hMod);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *phMod = hMod;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync }
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync if (pAddr)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *pAddr = pMap->Core.Key;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync if (piSeg)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *piSeg = pMap->iSeg;
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync RTDBGAS_UNLOCK_READ(pDbgAs);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync return VINF_SUCCESS;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync}
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsyncRT_EXPORT_SYMBOL(RTDbgAsModuleByAddr);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/**
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Queries mapping module information by name.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @returns IPRT status code.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @retval VERR_NOT_FOUND if no mapping was found at the specified address.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @retval VERR_OUT_OF_RANGE if the name index was out of range.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param hDbgAs The address space handle.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param pszName The module name.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param iName There can be more than one module by the same name
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * in an address space. This argument indicates which
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync * is meant. (0 based)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param phMod Where to the return the retained module handle.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsyncRTDECL(int) RTDbgAsModuleByName(RTDBGAS hDbgAs, const char *pszName, uint32_t iName, PRTDBGMOD phMod)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync{
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Validate input.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync PRTDBGASINT pDbgAs = hDbgAs;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, VERR_INVALID_HANDLE);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync AssertPtrReturn(phMod, VERR_INVALID_POINTER);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync RTDBGAS_LOCK_READ(pDbgAs);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync PRTDBGASNAME pName = (PRTDBGASNAME)RTStrSpaceGet(&pDbgAs->NameSpace, pszName);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync if (!pName)
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync {
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync RTDBGAS_UNLOCK_READ(pDbgAs);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync return VERR_NOT_FOUND;
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync }
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync PRTDBGASMOD pMod = pName->pHead;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync while (iName-- > 0)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync {
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync pMod = pMod->pNextName;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync if (!pMod)
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync {
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync RTDBGAS_UNLOCK_READ(pDbgAs);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync return VERR_OUT_OF_RANGE;
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync }
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync }
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Get, retain and return it.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTDBGMOD hMod = (RTDBGMOD)pMod->Core.Key;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTDbgModRetain(hMod);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *phMod = hMod;
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync RTDBGAS_UNLOCK_READ(pDbgAs);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync return VINF_SUCCESS;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync}
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsyncRT_EXPORT_SYMBOL(RTDbgAsModuleByName);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync/**
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync * Queries mapping information for a module given by index.
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync *
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync * @returns IRPT status code.
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync * @retval VERR_INVALID_HANDLE if hDbgAs is invalid.
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync * @retval VERR_OUT_OF_RANGE if the name index was out of range.
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync * @retval VINF_BUFFER_OVERFLOW if the array is too small and the returned
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync * information is incomplete.
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync *
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync * @param hDbgAs The address space handle.
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync * @param iModule The index of the module to get.
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync * @param paMappings Where to return the mapping information. The buffer
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync * size is given by *pcMappings.
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync * @param pcMappings IN: Size of the paMappings array. OUT: The number of
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync * entries returned.
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync * @param fFlags Flags for reserved for future use. MBZ.
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync *
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync * @remarks See remarks for RTDbgAsModuleByIndex regarding the volatility of the
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync * iModule parameter.
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync */
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsyncRTDECL(int) RTDbgAsModuleQueryMapByIndex(RTDBGAS hDbgAs, uint32_t iModule, PRTDBGASMAPINFO paMappings, uint32_t *pcMappings, uint32_t fFlags)
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync{
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync /*
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync * Validate input.
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync */
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync uint32_t const cMappings = *pcMappings;
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync PRTDBGASINT pDbgAs = hDbgAs;
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, VERR_INVALID_HANDLE);
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync AssertReturn(!fFlags, VERR_INVALID_PARAMETER);
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync RTDBGAS_LOCK_READ(pDbgAs);
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync if (iModule >= pDbgAs->cModules)
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync {
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync RTDBGAS_UNLOCK_READ(pDbgAs);
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync return VERR_OUT_OF_RANGE;
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync }
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync /*
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync * Copy the mapping information about the module.
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync */
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync int rc = VINF_SUCCESS;
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync PRTDBGASMAP pMap = pDbgAs->papModules[iModule]->pMapHead;
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync uint32_t cMaps = 0;
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync while (pMap)
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync {
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync if (cMaps >= cMappings)
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync {
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync rc = VINF_BUFFER_OVERFLOW;
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync break;
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync }
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync paMappings[cMaps].Address = pMap->Core.Key;
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync paMappings[cMaps].iSeg = pMap->iSeg;
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync cMaps++;
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync pMap = pMap->pNext;
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync }
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync RTDBGAS_UNLOCK_READ(pDbgAs);
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync *pcMappings = cMaps;
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync return rc;
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync}
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsyncRT_EXPORT_SYMBOL(RTDbgAsModuleQueryMapByIndex);
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync
9b19ad593b379ebfcc8273f85b90763b14b1da63vboxsync
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync/**
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * Internal worker that looks up and retains a module.
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync *
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * @returns Module handle, NIL_RTDBGMOD if not found.
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * @param pDbgAs The address space instance data.
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * @param Addr Address within the module.
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * @param piSeg where to return the segment index.
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * @param poffSeg Where to return the segment offset.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * @param pMapAddr The mapping address (RTDBGASMAP::Core.Key).
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsyncDECLINLINE(RTDBGMOD) rtDbgAsModuleByAddr(PRTDBGASINT pDbgAs, RTUINTPTR Addr, PRTDBGSEGIDX piSeg, PRTUINTPTR poffSeg, PRTUINTPTR pMapAddr)
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync{
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync RTDBGMOD hMod = NIL_RTDBGMOD;
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync RTDBGAS_LOCK_READ(pDbgAs);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync PRTDBGASMAP pMap = (PRTDBGASMAP)RTAvlrUIntPtrRangeGet(&pDbgAs->MapTree, Addr);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync if (pMap)
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync {
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync hMod = (RTDBGMOD)pMap->pMod->Core.Key;
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync RTDbgModRetain(hMod);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync *piSeg = pMap->iSeg != NIL_RTDBGSEGIDX ? pMap->iSeg : RTDBGSEGIDX_RVA;
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync *poffSeg = Addr - pMap->Core.Key;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync if (pMapAddr)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync *pMapAddr = pMap->Core.Key;
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync }
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync RTDBGAS_UNLOCK_READ(pDbgAs);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync return hMod;
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync}
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync/**
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * Adjusts the address to correspond to the mapping of the module/segment.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync *
88acfa6629a7976c0583c1712d2b5b22a87a5121vboxsync * @param pAddr The address to adjust (in/out).
88acfa6629a7976c0583c1712d2b5b22a87a5121vboxsync * @param iSeg The related segment.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * @param hDbgMod The module handle.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * @param MapAddr The mapping address.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * @param iMapSeg The segment that's mapped, NIL_RTDBGSEGIDX or
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * RTDBGSEGIDX_RVA if the whole module is mapped here.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsyncDECLINLINE(void) rtDbgAsAdjustAddressByMapping(PRTUINTPTR pAddr, RTDBGSEGIDX iSeg,
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync RTDBGMOD hDbgMod, RTUINTPTR MapAddr, RTDBGSEGIDX iMapSeg)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync{
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync if (iSeg == RTDBGSEGIDX_ABS)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync return;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync if (iSeg == RTDBGSEGIDX_RVA)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync {
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync if ( iMapSeg == RTDBGSEGIDX_RVA
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync || iMapSeg == NIL_RTDBGSEGIDX)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync *pAddr += MapAddr;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync else
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync {
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync RTUINTPTR SegRva = RTDbgModSegmentRva(hDbgMod, iMapSeg);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync AssertReturnVoid(SegRva != RTUINTPTR_MAX);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync AssertMsg(SegRva <= *pAddr, ("SegRva=%RTptr *pAddr=%RTptr\n", SegRva, *pAddr));
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync *pAddr += MapAddr - SegRva;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync }
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync }
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync else
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync {
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync if ( iMapSeg != RTDBGSEGIDX_RVA
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync && iMapSeg != NIL_RTDBGSEGIDX)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync {
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync Assert(iMapSeg == iSeg);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync *pAddr += MapAddr;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync }
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync else
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync {
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync RTUINTPTR SegRva = RTDbgModSegmentRva(hDbgMod, iSeg);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync AssertReturnVoid(SegRva != RTUINTPTR_MAX);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync *pAddr += MapAddr + SegRva;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync }
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync }
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync}
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync/**
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * Adjusts the symbol value to correspond to the mapping of the module/segment.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync *
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * @param pSymbol The returned symbol info.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * @param hDbgMod The module handle.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * @param MapAddr The mapping address.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * @param iMapSeg The segment that's mapped, NIL_RTDBGSEGIDX if the
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * whole module is mapped here.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsyncDECLINLINE(void) rtDbgAsAdjustSymbolValue(PRTDBGSYMBOL pSymbol, RTDBGMOD hDbgMod, RTUINTPTR MapAddr, RTDBGSEGIDX iMapSeg)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync{
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync Assert(pSymbol->iSeg != NIL_RTDBGSEGIDX);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync Assert(pSymbol->offSeg == pSymbol->Value);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync rtDbgAsAdjustAddressByMapping(&pSymbol->Value, pSymbol->iSeg, hDbgMod, MapAddr, iMapSeg);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync}
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync/**
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * Adjusts the line number address to correspond to the mapping of the module/segment.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync *
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * @param pLine The returned line number info.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * @param hDbgMod The module handle.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * @param MapAddr The mapping address.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * @param iMapSeg The segment that's mapped, NIL_RTDBGSEGIDX if the
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * whole module is mapped here.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsyncDECLINLINE(void) rtDbgAsAdjustLineAddress(PRTDBGLINE pLine, RTDBGMOD hDbgMod, RTUINTPTR MapAddr, RTDBGSEGIDX iMapSeg)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync{
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync Assert(pLine->iSeg != NIL_RTDBGSEGIDX);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync Assert(pLine->offSeg == pLine->Address);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync rtDbgAsAdjustAddressByMapping(&pLine->Address, pLine->iSeg, hDbgMod, MapAddr, iMapSeg);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync}
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/**
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Adds a symbol to a module in the address space.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @returns IPRT status code. See RTDbgModSymbolAdd for more specific ones.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @retval VERR_INVALID_HANDLE if hDbgAs is invalid.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @retval VERR_NOT_FOUND if no module was found at the specified address.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * @retval VERR_NOT_SUPPORTED if the module interpret doesn't support adding
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * custom symbols.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param hDbgAs The address space handle.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param pszSymbol The symbol name.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param Addr The address of the symbol.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param cb The size of the symbol.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * @param fFlags Symbol flags.
88acfa6629a7976c0583c1712d2b5b22a87a5121vboxsync * @param piOrdinal Where to return the symbol ordinal on success. If
88acfa6629a7976c0583c1712d2b5b22a87a5121vboxsync * the interpreter doesn't do ordinals, this will be set to
88acfa6629a7976c0583c1712d2b5b22a87a5121vboxsync * UINT32_MAX. Optional
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
044af0d1e6474076366759db86f101778c5f20ccvboxsyncRTDECL(int) RTDbgAsSymbolAdd(RTDBGAS hDbgAs, const char *pszSymbol, RTUINTPTR Addr, RTUINTPTR cb, uint32_t fFlags, uint32_t *piOrdinal)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync{
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * Validate input and resolve the address.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync PRTDBGASINT pDbgAs = hDbgAs;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, VERR_INVALID_HANDLE);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync
f87d3b252b04618a4258c870fbb3b740215808f5vboxsync RTDBGSEGIDX iSeg = NIL_RTDBGSEGIDX; /* shut up gcc */
f87d3b252b04618a4258c870fbb3b740215808f5vboxsync RTUINTPTR offSeg = 0;
f87d3b252b04618a4258c870fbb3b740215808f5vboxsync RTDBGMOD hMod = rtDbgAsModuleByAddr(pDbgAs, Addr, &iSeg, &offSeg, NULL);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync if (hMod == NIL_RTDBGMOD)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync return VERR_NOT_FOUND;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Forward the call.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
044af0d1e6474076366759db86f101778c5f20ccvboxsync int rc = RTDbgModSymbolAdd(hMod, pszSymbol, iSeg, offSeg, cb, fFlags, piOrdinal);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync RTDbgModRelease(hMod);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync return rc;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync}
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsyncRT_EXPORT_SYMBOL(RTDbgAsSymbolAdd);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync/**
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync * Creates a snapshot of the module table on the temporary heap.
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync *
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync * The caller must release all the module handles before freeing the table
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync * using RTMemTmpFree.
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync *
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync * @returns Module table snaphot.
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync * @param pDbgAs The address space instance data.
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync * @param pcModules Where to return the number of modules.
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync */
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsyncstatic PRTDBGMOD rtDbgAsSnapshotModuleTable(PRTDBGASINT pDbgAs, uint32_t *pcModules)
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync{
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync RTDBGAS_LOCK_READ(pDbgAs);
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync uint32_t iMod = *pcModules = pDbgAs->cModules;
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync PRTDBGMOD pahModules = (PRTDBGMOD)RTMemTmpAlloc(sizeof(pahModules[0]) * RT_MAX(iMod, 1));
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync if (pahModules)
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync {
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync while (iMod-- > 0)
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync {
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync RTDBGMOD hMod = (RTDBGMOD)pDbgAs->papModules[iMod]->Core.Key;
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync pahModules[iMod] = hMod;
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync RTDbgModRetain(hMod);
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync }
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync }
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync RTDBGAS_UNLOCK_READ(pDbgAs);
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync return pahModules;
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync}
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/**
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Query a symbol by address.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @returns IPRT status code. See RTDbgModSymbolAddr for more specific ones.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @retval VERR_INVALID_HANDLE if hDbgAs is invalid.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @retval VERR_NOT_FOUND if the address couldn't be mapped to a module.
2d8870843ff566fee9bd3a6a5942414254106479vboxsync * @retval VERR_INVALID_PARAMETER if incorrect flags.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param hDbgAs The address space handle.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param Addr The address which closest symbol is requested.
2d8870843ff566fee9bd3a6a5942414254106479vboxsync * @param fFlags Symbol search flags, see RTDBGSYMADDR_FLAGS_XXX.
2d8870843ff566fee9bd3a6a5942414254106479vboxsync * @param poffDisp Where to return the distance between the symbol and
2d8870843ff566fee9bd3a6a5942414254106479vboxsync * address. Optional.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param pSymbol Where to return the symbol info.
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync * @param phMod Where to return the module handle. Optional.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
2d8870843ff566fee9bd3a6a5942414254106479vboxsyncRTDECL(int) RTDbgAsSymbolByAddr(RTDBGAS hDbgAs, RTUINTPTR Addr, uint32_t fFlags,
2d8870843ff566fee9bd3a6a5942414254106479vboxsync PRTINTPTR poffDisp, PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync{
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * Validate input and resolve the address.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync PRTDBGASINT pDbgAs = hDbgAs;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, VERR_INVALID_HANDLE);
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync if (phMod)
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync *phMod = NIL_RTDBGMOD;
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync
f87d3b252b04618a4258c870fbb3b740215808f5vboxsync RTDBGSEGIDX iSeg = NIL_RTDBGSEGIDX; /* shut up gcc */
f87d3b252b04618a4258c870fbb3b740215808f5vboxsync RTUINTPTR offSeg = 0;
f87d3b252b04618a4258c870fbb3b740215808f5vboxsync RTUINTPTR MapAddr = 0;
f87d3b252b04618a4258c870fbb3b740215808f5vboxsync RTDBGMOD hMod = rtDbgAsModuleByAddr(pDbgAs, Addr, &iSeg, &offSeg, &MapAddr);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync if (hMod == NIL_RTDBGMOD)
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync {
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync /*
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync * Check for absolute symbols. Requires iterating all modules.
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync */
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync uint32_t cModules;
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync PRTDBGMOD pahModules = rtDbgAsSnapshotModuleTable(pDbgAs, &cModules);
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync if (!pahModules)
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync return VERR_NO_TMP_MEMORY;
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync int rc;
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync RTINTPTR offBestDisp = RTINTPTR_MAX;
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync uint32_t iBest = UINT32_MAX;
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync for (uint32_t i = 0; i < cModules; i++)
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync {
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync RTINTPTR offDisp;
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync rc = RTDbgModSymbolByAddr(pahModules[i], RTDBGSEGIDX_ABS, Addr, fFlags, &offDisp, pSymbol);
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync if (RT_SUCCESS(rc) && RT_ABS(offDisp) < offBestDisp)
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync {
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync offBestDisp = RT_ABS(offDisp);
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync iBest = i;
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync }
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync }
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync if (iBest == UINT32_MAX)
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync rc = VERR_NOT_FOUND;
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync else
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync {
848a8a60f4429fb74d007753d6a2e588d38516dfvboxsync hMod = pahModules[iBest];
848a8a60f4429fb74d007753d6a2e588d38516dfvboxsync rc = RTDbgModSymbolByAddr(hMod, RTDBGSEGIDX_ABS, Addr, fFlags, poffDisp, pSymbol);
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync if (RT_SUCCESS(rc))
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync {
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync rtDbgAsAdjustSymbolValue(pSymbol, hMod, MapAddr, iSeg);
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync if (phMod)
848a8a60f4429fb74d007753d6a2e588d38516dfvboxsync RTDbgModRetain(*phMod = hMod);
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync }
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync }
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync for (uint32_t i = 0; i < cModules; i++)
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync RTDbgModRelease(pahModules[i]);
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync RTMemTmpFree(pahModules);
14d6fbe750318c92111564423ffb6cee9290ac6cvboxsync return rc;
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync }
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Forward the call.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
2d8870843ff566fee9bd3a6a5942414254106479vboxsync int rc = RTDbgModSymbolByAddr(hMod, iSeg, offSeg, fFlags, poffDisp, pSymbol);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync if (RT_SUCCESS(rc))
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync rtDbgAsAdjustSymbolValue(pSymbol, hMod, MapAddr, iSeg);
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync if (phMod)
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync *phMod = hMod;
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync else
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync RTDbgModRelease(hMod);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync return rc;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync}
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsyncRT_EXPORT_SYMBOL(RTDbgAsSymbolByAddr);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/**
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Query a symbol by address.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @returns IPRT status code. See RTDbgModSymbolAddrA for more specific ones.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @retval VERR_INVALID_HANDLE if hDbgAs is invalid.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @retval VERR_NOT_FOUND if the address couldn't be mapped to a module.
2d8870843ff566fee9bd3a6a5942414254106479vboxsync * @retval VERR_INVALID_PARAMETER if incorrect flags.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param hDbgAs The address space handle.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param Addr The address which closest symbol is requested.
2d8870843ff566fee9bd3a6a5942414254106479vboxsync * @param fFlags Symbol search flags, see RTDBGSYMADDR_FLAGS_XXX.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param poffDisp Where to return the distance between the symbol
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * and address. Optional.
88acfa6629a7976c0583c1712d2b5b22a87a5121vboxsync * @param ppSymInfo Where to return the pointer to the allocated symbol
88acfa6629a7976c0583c1712d2b5b22a87a5121vboxsync * info. Always set. Free with RTDbgSymbolFree.
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync * @param phMod Where to return the module handle. Optional.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
2d8870843ff566fee9bd3a6a5942414254106479vboxsyncRTDECL(int) RTDbgAsSymbolByAddrA(RTDBGAS hDbgAs, RTUINTPTR Addr, uint32_t fFlags,
2d8870843ff566fee9bd3a6a5942414254106479vboxsync PRTINTPTR poffDisp, PRTDBGSYMBOL *ppSymInfo, PRTDBGMOD phMod)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync{
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * Validate input and resolve the address.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync PRTDBGASINT pDbgAs = hDbgAs;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, VERR_INVALID_HANDLE);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync
f87d3b252b04618a4258c870fbb3b740215808f5vboxsync RTDBGSEGIDX iSeg = NIL_RTDBGSEGIDX;
f87d3b252b04618a4258c870fbb3b740215808f5vboxsync RTUINTPTR offSeg = 0;
f87d3b252b04618a4258c870fbb3b740215808f5vboxsync RTUINTPTR MapAddr = 0;
f87d3b252b04618a4258c870fbb3b740215808f5vboxsync RTDBGMOD hMod = rtDbgAsModuleByAddr(pDbgAs, Addr, &iSeg, &offSeg, &MapAddr);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync if (hMod == NIL_RTDBGMOD)
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync {
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync if (phMod)
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync *phMod = NIL_RTDBGMOD;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync return VERR_NOT_FOUND;
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync }
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Forward the call.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
2d8870843ff566fee9bd3a6a5942414254106479vboxsync int rc = RTDbgModSymbolByAddrA(hMod, iSeg, offSeg, fFlags, poffDisp, ppSymInfo);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync if (RT_SUCCESS(rc))
88acfa6629a7976c0583c1712d2b5b22a87a5121vboxsync rtDbgAsAdjustSymbolValue(*ppSymInfo, hMod, MapAddr, iSeg);
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync if (phMod)
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync *phMod = hMod;
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync else
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync RTDbgModRelease(hMod);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync return rc;
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync}
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsyncRT_EXPORT_SYMBOL(RTDbgAsSymbolByAddrA);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync/**
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * Attempts to find a mapping of the specified symbol/module and
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * adjust it's Value field accordingly.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync *
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * @returns true / false success indicator.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * @param pDbgAs The address space.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * @param hDbgMod The module handle.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * @param pSymbol The symbol info.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsyncstatic bool rtDbgAsFindMappingAndAdjustSymbolValue(PRTDBGASINT pDbgAs, RTDBGMOD hDbgMod, PRTDBGSYMBOL pSymbol)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync{
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /*
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * Absolute segments needs no fixing.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync RTDBGSEGIDX const iSeg = pSymbol->iSeg;
77b92045ecae7978726dd23cb3d5de4676aec1c9vboxsync if (iSeg == RTDBGSEGIDX_ABS)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync return true;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync RTDBGAS_LOCK_READ(pDbgAs);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /*
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * Lookup up the module by it's handle and iterate the mappings looking for one
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * that either encompasses the entire module or the segment in question.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync PRTDBGASMOD pMod = (PRTDBGASMOD)RTAvlPVGet(&pDbgAs->ModTree, hDbgMod);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync if (pMod)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync {
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync for (PRTDBGASMAP pMap = pMod->pMapHead; pMap; pMap = pMap->pNext)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync {
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /* Exact segment match or full-mapping. */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync if ( iSeg == pMap->iSeg
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync || pMap->iSeg == NIL_RTDBGSEGIDX)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync {
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync RTUINTPTR MapAddr = pMap->Core.Key;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync RTDBGSEGIDX iMapSeg = pMap->iSeg;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync RTDBGAS_UNLOCK_READ(pDbgAs);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync rtDbgAsAdjustSymbolValue(pSymbol, hDbgMod, MapAddr, iMapSeg);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync return true;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync }
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /* Symbol uses RVA and the mapping doesn't, see if it's in the mapped segment. */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync if (iSeg == RTDBGSEGIDX_RVA)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync {
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync Assert(pMap->iSeg != NIL_RTDBGSEGIDX);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync RTUINTPTR SegRva = RTDbgModSegmentRva(hDbgMod, pMap->iSeg);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync Assert(SegRva != RTUINTPTR_MAX);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync RTUINTPTR cbSeg = RTDbgModSegmentSize(hDbgMod, pMap->iSeg);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync if (SegRva - pSymbol->Value < cbSeg)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync {
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync RTUINTPTR MapAddr = pMap->Core.Key;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync RTDBGSEGIDX iMapSeg = pMap->iSeg;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync RTDBGAS_UNLOCK_READ(pDbgAs);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync rtDbgAsAdjustSymbolValue(pSymbol, hDbgMod, MapAddr, iMapSeg);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync return true;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync }
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync }
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync }
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync }
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /* else: Unmapped while we were searching. */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync RTDBGAS_UNLOCK_READ(pDbgAs);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync return false;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync}
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/**
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Query a symbol by name.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @returns IPRT status code.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @retval VERR_SYMBOL_NOT_FOUND if not found.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param hDbgAs The address space handle.
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync * @param pszSymbol The symbol name. It is possible to limit the scope
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync * of the search by prefixing the symbol with a module
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync * name pattern followed by a bang (!) character.
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync * RTStrSimplePatternNMatch is used for the matching.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param pSymbol Where to return the symbol info.
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync * @param phMod Where to return the module handle. Optional.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsyncRTDECL(int) RTDbgAsSymbolByName(RTDBGAS hDbgAs, const char *pszSymbol, PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync{
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Validate input.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync PRTDBGASINT pDbgAs = hDbgAs;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, VERR_INVALID_HANDLE);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync AssertPtrReturn(pszSymbol, VERR_INVALID_POINTER);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync AssertPtrReturn(pSymbol, VERR_INVALID_POINTER);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync /*
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync * Look for module pattern.
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync */
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync const char *pachModPat = NULL;
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync size_t cchModPat = 0;
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync const char *pszBang = strchr(pszSymbol, '!');
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync if (pszBang)
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync {
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync pachModPat = pszSymbol;
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync cchModPat = pszBang - pszSymbol;
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync pszSymbol = pszBang + 1;
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync if (!*pszSymbol)
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync return VERR_DBG_SYMBOL_NAME_OUT_OF_RANGE;
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync /* Note! Zero length module -> no pattern -> escape for symbol with '!'. */
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync }
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Iterate the modules, looking for the symbol.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync uint32_t cModules;
8df047381fb076540a191d281498b66ba9182dbdvboxsync PRTDBGMOD pahModules = rtDbgAsSnapshotModuleTable(pDbgAs, &cModules);
8df047381fb076540a191d281498b66ba9182dbdvboxsync if (!pahModules)
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync return VERR_NO_TMP_MEMORY;
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync for (uint32_t i = 0; i < cModules; i++)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync {
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync if ( cchModPat == 0
8df047381fb076540a191d281498b66ba9182dbdvboxsync || RTStrSimplePatternNMatch(pachModPat, cchModPat, RTDbgModName(pahModules[i]), RTSTR_MAX))
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync {
8df047381fb076540a191d281498b66ba9182dbdvboxsync int rc = RTDbgModSymbolByName(pahModules[i], pszSymbol, pSymbol);
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync if (RT_SUCCESS(rc))
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync {
8df047381fb076540a191d281498b66ba9182dbdvboxsync if (rtDbgAsFindMappingAndAdjustSymbolValue(pDbgAs, pahModules[i], pSymbol))
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync {
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync if (phMod)
8df047381fb076540a191d281498b66ba9182dbdvboxsync RTDbgModRetain(*phMod = pahModules[i]);
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync for (; i < cModules; i++)
8df047381fb076540a191d281498b66ba9182dbdvboxsync RTDbgModRelease(pahModules[i]);
8df047381fb076540a191d281498b66ba9182dbdvboxsync RTMemTmpFree(pahModules);
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync return rc;
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync }
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync }
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync }
8df047381fb076540a191d281498b66ba9182dbdvboxsync RTDbgModRelease(pahModules[i]);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync }
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync
8df047381fb076540a191d281498b66ba9182dbdvboxsync RTMemTmpFree(pahModules);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync return VERR_SYMBOL_NOT_FOUND;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync}
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsyncRT_EXPORT_SYMBOL(RTDbgAsSymbolByName);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/**
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync * Query a symbol by name, allocating the returned symbol structure.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @returns IPRT status code.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @retval VERR_SYMBOL_NOT_FOUND if not found.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param hDbgAs The address space handle.
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync * @param pszSymbol The symbol name. See RTDbgAsSymbolByName for more.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * @param ppSymbol Where to return the pointer to the allocated
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * symbol info. Always set. Free with RTDbgSymbolFree.
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync * @param phMod Where to return the module handle. Optional.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsyncRTDECL(int) RTDbgAsSymbolByNameA(RTDBGAS hDbgAs, const char *pszSymbol, PRTDBGSYMBOL *ppSymbol, PRTDBGMOD phMod)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync{
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Validate input.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync AssertPtrReturn(ppSymbol, VERR_INVALID_POINTER);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync *ppSymbol = NULL;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync PRTDBGASINT pDbgAs = hDbgAs;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, VERR_INVALID_HANDLE);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync AssertPtrReturn(pszSymbol, VERR_INVALID_POINTER);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync /*
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync * Look for module pattern.
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync */
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync const char *pachModPat = NULL;
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync size_t cchModPat = 0;
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync const char *pszBang = strchr(pszSymbol, '!');
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync if (pszBang)
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync {
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync pachModPat = pszSymbol;
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync cchModPat = pszBang - pszSymbol;
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync pszSymbol = pszBang + 1;
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync if (!*pszSymbol)
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync return VERR_DBG_SYMBOL_NAME_OUT_OF_RANGE;
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync /* Note! Zero length module -> no pattern -> escape for symbol with '!'. */
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync }
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Iterate the modules, looking for the symbol.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync uint32_t cModules;
8df047381fb076540a191d281498b66ba9182dbdvboxsync PRTDBGMOD pahModules = rtDbgAsSnapshotModuleTable(pDbgAs, &cModules);
8df047381fb076540a191d281498b66ba9182dbdvboxsync if (!pahModules)
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync return VERR_NO_TMP_MEMORY;
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync for (uint32_t i = 0; i < cModules; i++)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync {
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync if ( cchModPat == 0
8df047381fb076540a191d281498b66ba9182dbdvboxsync || RTStrSimplePatternNMatch(pachModPat, cchModPat, RTDbgModName(pahModules[i]), RTSTR_MAX))
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync {
8df047381fb076540a191d281498b66ba9182dbdvboxsync int rc = RTDbgModSymbolByNameA(pahModules[i], pszSymbol, ppSymbol);
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync if (RT_SUCCESS(rc))
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync {
8df047381fb076540a191d281498b66ba9182dbdvboxsync if (rtDbgAsFindMappingAndAdjustSymbolValue(pDbgAs, pahModules[i], *ppSymbol))
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync {
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync if (phMod)
8df047381fb076540a191d281498b66ba9182dbdvboxsync RTDbgModRetain(*phMod = pahModules[i]);
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync for (; i < cModules; i++)
8df047381fb076540a191d281498b66ba9182dbdvboxsync RTDbgModRelease(pahModules[i]);
8df047381fb076540a191d281498b66ba9182dbdvboxsync RTMemTmpFree(pahModules);
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync return rc;
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync }
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync }
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync }
8df047381fb076540a191d281498b66ba9182dbdvboxsync RTDbgModRelease(pahModules[i]);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync }
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync
8df047381fb076540a191d281498b66ba9182dbdvboxsync RTMemTmpFree(pahModules);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync return VERR_SYMBOL_NOT_FOUND;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync}
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsyncRT_EXPORT_SYMBOL(RTDbgAsSymbolByNameA);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync/**
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * Adds a line number to a module in the address space.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync *
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * @returns IPRT status code. See RTDbgModSymbolAdd for more specific ones.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * @retval VERR_INVALID_HANDLE if hDbgAs is invalid.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * @retval VERR_NOT_FOUND if no module was found at the specified address.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * @retval VERR_NOT_SUPPORTED if the module interpret doesn't support adding
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * custom symbols.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync *
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * @param hDbgAs The address space handle.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * @param pszFile The file name.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * @param uLineNo The line number.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * @param Addr The address of the symbol.
044af0d1e6474076366759db86f101778c5f20ccvboxsync * @param piOrdinal Where to return the line number ordinal on success.
044af0d1e6474076366759db86f101778c5f20ccvboxsync * If the interpreter doesn't do ordinals, this will be
044af0d1e6474076366759db86f101778c5f20ccvboxsync * set to UINT32_MAX. Optional.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync */
044af0d1e6474076366759db86f101778c5f20ccvboxsyncRTDECL(int) RTDbgAsLineAdd(RTDBGAS hDbgAs, const char *pszFile, uint32_t uLineNo, RTUINTPTR Addr, uint32_t *piOrdinal)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync{
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /*
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * Validate input and resolve the address.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync PRTDBGASINT pDbgAs = hDbgAs;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, VERR_INVALID_HANDLE);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
f87d3b252b04618a4258c870fbb3b740215808f5vboxsync RTDBGSEGIDX iSeg = NIL_RTDBGSEGIDX; /* shut up gcc */
f87d3b252b04618a4258c870fbb3b740215808f5vboxsync RTUINTPTR offSeg = 0; /* ditto */
f87d3b252b04618a4258c870fbb3b740215808f5vboxsync RTDBGMOD hMod = rtDbgAsModuleByAddr(pDbgAs, Addr, &iSeg, &offSeg, NULL);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync if (hMod == NIL_RTDBGMOD)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync return VERR_NOT_FOUND;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /*
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * Forward the call.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync */
044af0d1e6474076366759db86f101778c5f20ccvboxsync int rc = RTDbgModLineAdd(hMod, pszFile, uLineNo, iSeg, offSeg, piOrdinal);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync RTDbgModRelease(hMod);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync return rc;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync}
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsyncRT_EXPORT_SYMBOL(RTDbgAsLineAdd);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
682342827b0e80c493c820603508e79e76c42658vboxsyncRTDECL(int) RTDbgAsLineByAddr(RTDBGAS hDbgAs, RTUINTPTR Addr, PRTINTPTR poffDisp, PRTDBGLINE pLine, PRTDBGMOD phMod)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync{
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * Validate input and resolve the address.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync PRTDBGASINT pDbgAs = hDbgAs;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, VERR_INVALID_HANDLE);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync
f87d3b252b04618a4258c870fbb3b740215808f5vboxsync RTDBGSEGIDX iSeg = NIL_RTDBGSEGIDX; /* shut up gcc */
f87d3b252b04618a4258c870fbb3b740215808f5vboxsync RTUINTPTR offSeg = 0;
f87d3b252b04618a4258c870fbb3b740215808f5vboxsync RTUINTPTR MapAddr = 0;
f87d3b252b04618a4258c870fbb3b740215808f5vboxsync RTDBGMOD hMod = rtDbgAsModuleByAddr(pDbgAs, Addr, &iSeg, &offSeg, &MapAddr);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync if (hMod == NIL_RTDBGMOD)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync return VERR_NOT_FOUND;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Forward the call.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync int rc = RTDbgModLineByAddr(hMod, iSeg, offSeg, poffDisp, pLine);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync if (RT_SUCCESS(rc))
682342827b0e80c493c820603508e79e76c42658vboxsync {
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync rtDbgAsAdjustLineAddress(pLine, hMod, MapAddr, iSeg);
682342827b0e80c493c820603508e79e76c42658vboxsync if (phMod)
682342827b0e80c493c820603508e79e76c42658vboxsync *phMod = hMod;
682342827b0e80c493c820603508e79e76c42658vboxsync else
682342827b0e80c493c820603508e79e76c42658vboxsync RTDbgModRelease(hMod);
682342827b0e80c493c820603508e79e76c42658vboxsync }
682342827b0e80c493c820603508e79e76c42658vboxsync else
682342827b0e80c493c820603508e79e76c42658vboxsync RTDbgModRelease(hMod);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync return rc;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync}
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsyncRT_EXPORT_SYMBOL(RTDbgAsLineByAddr);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
682342827b0e80c493c820603508e79e76c42658vboxsyncRTDECL(int) RTDbgAsLineByAddrA(RTDBGAS hDbgAs, RTUINTPTR Addr, PRTINTPTR poffDisp, PRTDBGLINE *ppLine, PRTDBGMOD phMod)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync{
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * Validate input and resolve the address.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync PRTDBGASINT pDbgAs = hDbgAs;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, VERR_INVALID_HANDLE);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync
f87d3b252b04618a4258c870fbb3b740215808f5vboxsync RTDBGSEGIDX iSeg = NIL_RTDBGSEGIDX; /* shut up gcc */
f87d3b252b04618a4258c870fbb3b740215808f5vboxsync RTUINTPTR offSeg = 0;
f87d3b252b04618a4258c870fbb3b740215808f5vboxsync RTUINTPTR MapAddr = 0;
f87d3b252b04618a4258c870fbb3b740215808f5vboxsync RTDBGMOD hMod = rtDbgAsModuleByAddr(pDbgAs, Addr, &iSeg, &offSeg, &MapAddr);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync if (hMod == NIL_RTDBGMOD)
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync return VERR_NOT_FOUND;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync /*
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Forward the call.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync */
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync int rc = RTDbgModLineByAddrA(hMod, iSeg, offSeg, poffDisp, ppLine);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync if (RT_SUCCESS(rc))
682342827b0e80c493c820603508e79e76c42658vboxsync {
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync rtDbgAsAdjustLineAddress(*ppLine, hMod, MapAddr, iSeg);
682342827b0e80c493c820603508e79e76c42658vboxsync if (phMod)
682342827b0e80c493c820603508e79e76c42658vboxsync *phMod = hMod;
682342827b0e80c493c820603508e79e76c42658vboxsync else
682342827b0e80c493c820603508e79e76c42658vboxsync RTDbgModRelease(hMod);
682342827b0e80c493c820603508e79e76c42658vboxsync }
682342827b0e80c493c820603508e79e76c42658vboxsync else
682342827b0e80c493c820603508e79e76c42658vboxsync RTDbgModRelease(hMod);
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync return rc;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync}
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsyncRT_EXPORT_SYMBOL(RTDbgAsLineByAddrA);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync