dbgas.cpp revision 9d020a0622f95aec3aabaff436a495e88dbbd71a
11d3005e2935c925665896fa26fde09b3e656d70vboxsync/* $Id$ */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/** @file
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * IPRT - Debug Address Space.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
e64031e20c39650a7bc902a3e1aba613b9415deevboxsync/*
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Copyright (C) 2009 Sun Microsystems, Inc.
cf5f6bf2704d4fff443139e10bccc6a0a7fa4b85vboxsync *
cf5f6bf2704d4fff443139e10bccc6a0a7fa4b85vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
cf5f6bf2704d4fff443139e10bccc6a0a7fa4b85vboxsync * available from http://www.virtualbox.org. This file is free software;
cf5f6bf2704d4fff443139e10bccc6a0a7fa4b85vboxsync * you can redistribute it and/or modify it under the terms of the GNU
cf5f6bf2704d4fff443139e10bccc6a0a7fa4b85vboxsync * General Public License (GPL) as published by the Free Software
cf5f6bf2704d4fff443139e10bccc6a0a7fa4b85vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
cf5f6bf2704d4fff443139e10bccc6a0a7fa4b85vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * The contents of this file may alternatively be used under the terms
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * of the Common Development and Distribution License Version 1.0
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * VirtualBox OSE distribution, in which case the provisions of the
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * CDDL are applicable instead of those of the GPL.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * You may elect to license modified versions of this file under the
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * terms and conditions of either the GPL or the CDDL or both.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * additional information or have any questions.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/*******************************************************************************
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync* Header Files *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync*******************************************************************************/
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#include <iprt/dbg.h>
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#include <iprt/asm.h>
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#include <iprt/avl.h>
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#include <iprt/assert.h>
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#include <iprt/err.h>
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#include <iprt/mem.h>
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#include <iprt/param.h>
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#include <iprt/string.h>
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#include <iprt/semaphore.h>
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#include "internal/magics.h"
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/*******************************************************************************
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync* Structures and Typedefs *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync*******************************************************************************/
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/** Pointer to a module table entry. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsynctypedef struct RTDBGASMOD *PRTDBGASMOD;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/** Pointer to an address space mapping node. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsynctypedef struct RTDBGASMAP *PRTDBGASMAP;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/** Pointer to a name head. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsynctypedef struct RTDBGASNAME *PRTDBGASNAME;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/**
79baed6836ae36c5f15b182292387484dcf7a752vboxsync * Module entry.
79baed6836ae36c5f15b182292387484dcf7a752vboxsync */
79baed6836ae36c5f15b182292387484dcf7a752vboxsynctypedef struct RTDBGASMOD
79baed6836ae36c5f15b182292387484dcf7a752vboxsync{
79baed6836ae36c5f15b182292387484dcf7a752vboxsync /** Node core, the module handle is the key. */
79baed6836ae36c5f15b182292387484dcf7a752vboxsync AVLPVNODECORE Core;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync /** Pointer to the first mapping of the module or a segment within it. */
79baed6836ae36c5f15b182292387484dcf7a752vboxsync PRTDBGASMAP pMapHead;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync /** Pointer to the next module with an identical name. */
79baed6836ae36c5f15b182292387484dcf7a752vboxsync PRTDBGASMOD pNextName;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync} RTDBGASMOD;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync
79baed6836ae36c5f15b182292387484dcf7a752vboxsync/**
79baed6836ae36c5f15b182292387484dcf7a752vboxsync * An address space mapping, either of a full module or a segment.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsynctypedef struct RTDBGASMAP
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync{
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /** The AVL node core. Contains the address range. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync AVLRUINTPTRNODECORE Core;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync /** Pointer to the next mapping of the module. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync PRTDBGASMAP pNext;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /** Pointer to the module. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync PRTDBGASMOD pMod;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /** Which segment in the module.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * This is NIL_RTDBGSEGIDX when the entire module is mapped. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTDBGSEGIDX iSeg;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync} RTDBGASMAP;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/**
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Name in the address space.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsynctypedef struct RTDBGASNAME
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync{
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /** The string space node core.*/
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTSTRSPACECORE StrCore;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /** The list of nodes */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync PRTDBGASMOD pHead;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync} RTDBGASNAME;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/**
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Debug address space instance.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsynctypedef struct RTDBGASINT
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync{
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /** Magic value (RTDBGAS_MAGIC). */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync uint32_t u32Magic;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /** The number of reference to this address space. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync uint32_t volatile cRefs;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /** Handle of the read-write lock. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTSEMRW hLock;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /** Number of modules in the module address space. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync uint32_t cModules;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /** Pointer to the module table.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * The valid array length is given by cModules. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync PRTDBGASMOD paModules;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /** AVL tree translating module handles to module entries. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync AVLPVTREE ModTree;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /** AVL tree mapping addresses to modules. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync AVLRUINTPTRTREE MapTree;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /** Names of the modules in the name space. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTSTRSPACE NameSpace;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /** The first address the AS. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTUINTPTR FirstAddr;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /** The last address in the AS. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTUINTPTR LastAddr;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /** The name of the address space. (variable length) */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync char szName[1];
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync} RTDBGASINT;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/** Pointer to an a debug address space instance. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsynctypedef RTDBGASINT *PRTDBGASINT;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/*******************************************************************************
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync* Defined Constants And Macros *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync*******************************************************************************/
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/** Validates an address space handle and returns rc if not valid. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#define RTDBGAS_VALID_RETURN_RC(pDbgAs, rc) \
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync do { \
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync AssertPtrReturn((pDbgAs), (rc)); \
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync AssertReturn((pDbgAs)->u32Magic == RTDBGAS_MAGIC, (rc)); \
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync AssertReturn((pDbgAs)->cRefs > 0, (rc)); \
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync } while (0)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/** Locks the address space for reading. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#define RTDBGAS_LOCK_READ(pDbgAs) \
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync do { \
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync int rcLock = RTSemRWRequestRead((pDbgAs)->hLock, RT_INDEFINITE_WAIT); \
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync AssertRC(rcLock); \
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync } while (0)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/** Unlocks the address space after reading. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#define RTDBGAS_UNLOCK_READ(pDbgAs) \
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync do { \
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync int rcLock = RTSemRWReleaseRead((pDbgAs)->hLock); \
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync AssertRC(rcLock); \
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync } while (0)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/** Locks the address space for writing. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#define RTDBGAS_LOCK_WRITE(pDbgAs) \
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync do { \
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync int rcLock = RTSemRWRequestWrite((pDbgAs)->hLock, RT_INDEFINITE_WAIT); \
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync AssertRC(rcLock); \
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync } while (0)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/** Unlocks the address space after writing. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#define RTDBGAS_UNLOCK_WRITE(pDbgAs) \
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync do { \
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync int rcLock = RTSemRWReleaseWrite((pDbgAs)->hLock); \
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync AssertRC(rcLock); \
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync } while (0)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/*******************************************************************************
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync* Internal Functions *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync*******************************************************************************/
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncstatic void rtDbgAsModuleUnlinkMod(PRTDBGASINT pDbgAs, PRTDBGASMOD pMod);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncstatic void rtDbgAsModuleUnlinkByMap(PRTDBGASINT pDbgAs, PRTDBGASMAP pMap);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/**
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Creates an empty address space.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @returns IPRT status code.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param phDbgAs Where to store the address space handle on success.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param FirstAddr The first address in the address space.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param LastAddr The last address in the address space.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param pszName The name of the address space.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncRTDECL(int) RTDbgAsCreate(PRTDBGAS phDbgAs, RTUINTPTR FirstAddr, RTUINTPTR LastAddr, const char *pszName)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync{
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /*
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Input validation.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync AssertPtrReturn(phDbgAs, VERR_INVALID_POINTER);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync AssertPtrReturn(pszName, VERR_INVALID_POINTER);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync AssertReturn(FirstAddr < LastAddr, VERR_INVALID_PARAMETER);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /*
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Allocate memory for the instance data.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync size_t cchName = strlen(pszName);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync PRTDBGASINT pDbgAs = (PRTDBGASINT)RTMemAlloc(RT_OFFSETOF(RTDBGASINT, szName[cchName + 1]));
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (!pDbgAs)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return VERR_NO_MEMORY;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /* initalize it. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync pDbgAs->u32Magic = RTDBGAS_MAGIC;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync pDbgAs->cRefs = 1;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync pDbgAs->hLock = NIL_RTSEMRW;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync pDbgAs->cModules = 0;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync pDbgAs->paModules = NULL;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync pDbgAs->ModTree = NULL;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync pDbgAs->MapTree = NULL;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync pDbgAs->NameSpace = NULL;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync pDbgAs->FirstAddr = FirstAddr;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync pDbgAs->LastAddr = LastAddr;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync memcpy(pDbgAs->szName, pszName, cchName + 1);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync int rc = RTSemRWCreate(&pDbgAs->hLock);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (RT_SUCCESS(rc))
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *phDbgAs = pDbgAs;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return VINF_SUCCESS;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync pDbgAs->u32Magic = 0;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTMemFree(pDbgAs);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return rc;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync}
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/**
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Variant of RTDbgAsCreate that takes a name format string.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @returns IPRT status code.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param phDbgAs Where to store the address space handle on success.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param FirstAddr The first address in the address space.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param LastAddr The last address in the address space.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param pszNameFmt The name format of the address space.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param va Format arguments.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncRTDECL(int) RTDbgAsCreateV(PRTDBGAS phDbgAs, RTUINTPTR FirstAddr, RTUINTPTR LastAddr, const char *pszNameFmt, va_list va)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync{
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync AssertPtrReturn(pszNameFmt, VERR_INVALID_POINTER);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync char *pszName;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTStrAPrintfV(&pszName, pszNameFmt, va);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (!pszName)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return VERR_NO_MEMORY;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync int rc = RTDbgAsCreate(phDbgAs, FirstAddr, LastAddr, pszName);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTStrFree(pszName);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return rc;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync}
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/**
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Variant of RTDbgAsCreate that takes a name format string.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @returns IPRT status code.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param phDbgAs Where to store the address space handle on success.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param FirstAddr The first address in the address space.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param LastAddr The last address in the address space.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param pszNameFmt The name format of the address space.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param ... Format arguments.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncRTDECL(int) RTDbgAsCreateF(PRTDBGAS phDbgAs, RTUINTPTR FirstAddr, RTUINTPTR LastAddr, const char *pszNameFmt, ...)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync{
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync va_list va;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync va_start(va, pszNameFmt);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync int rc = RTDbgAsCreateV(phDbgAs, FirstAddr, LastAddr, pszNameFmt, va);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync va_end(va);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return rc;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync}
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/**
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Callback used by RTDbgAsDestroy to free all mapping nodes.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @returns 0
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param pNode The map node.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param pvUser NULL.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncstatic DECLCALLBACK(int) rtDbgAsDestroyMapCallback(PAVLRUINTPTRNODECORE pNode, void *pvUser)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync{
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTMemFree(pNode);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync NOREF(pvUser);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return 0;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync}
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/**
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Callback used by RTDbgAsDestroy to free all name space nodes.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @returns 0
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param pStr The name node.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param pvUser NULL.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncstatic DECLCALLBACK(int) rtDbgAsDestroyNameCallback(PRTSTRSPACECORE pStr, void *pvUser)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync{
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTMemFree(pStr);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync NOREF(pvUser);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return 0;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync}
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/**
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Destroys the address space.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * This means unlinking all the modules it currently contains, potentially
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * causing some or all of them to be destroyed as they are managed by
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * reference counting.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param pDbgAs The address space instance to be destroyed.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncstatic void rtDbgAsDestroy(PRTDBGASINT pDbgAs)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync{
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /*
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Mark the address space invalid and release all the modules.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync ASMAtomicWriteU32(&pDbgAs->u32Magic, ~RTDBGAS_MAGIC);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTAvlrUIntPtrDestroy(&pDbgAs->MapTree, rtDbgAsDestroyMapCallback, NULL);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTStrSpaceDestroy(&pDbgAs->NameSpace, rtDbgAsDestroyNameCallback, NULL);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync uint32_t i = pDbgAs->cModules;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync while (i-- > 0)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTDbgModRelease((RTDBGMOD)pDbgAs->paModules[i].Core.Key);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync pDbgAs->paModules[i].Core.Key = NIL_RTDBGMOD;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTMemFree(pDbgAs->paModules);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync pDbgAs->paModules = NULL;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTMemFree(pDbgAs);
58ab0ad45444e80bdd970ddeb468d0872dbbbb47vboxsync}
11d3005e2935c925665896fa26fde09b3e656d70vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
58ab0ad45444e80bdd970ddeb468d0872dbbbb47vboxsync/**
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Retains another reference to the address space.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @returns New reference count, UINT32_MAX on invalid handle (asserted).
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param hDbgAs The address space handle.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @remarks Will not take any locks.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncRTDECL(uint32_t) RTDbgAsRetain(RTDBGAS hDbgAs)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync{
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync PRTDBGASINT pDbgAs = hDbgAs;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, UINT32_MAX);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return ASMAtomicIncU32(&pDbgAs->cRefs);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync}
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/**
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Release a reference to the address space.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * When the reference count reaches zero, the address space is destroyed.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * That means unlinking all the modules it currently contains, potentially
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * causing some or all of them to be destroyed as they are managed by
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * reference counting.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @returns New reference count, UINT32_MAX on invalid handle (asserted).
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param hDbgAs The address space handle. The NIL handle is quietly
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * ignored and 0 is returned.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @remarks Will not take any locks.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncRTDECL(uint32_t) RTDbgAsRelease(RTDBGAS hDbgAs)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync{
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (hDbgAs == NIL_RTDBGAS)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return 0;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync PRTDBGASINT pDbgAs = hDbgAs;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, UINT32_MAX);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync uint32_t cRefs = ASMAtomicDecU32(&pDbgAs->cRefs);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (!cRefs)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync rtDbgAsDestroy(pDbgAs);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return cRefs;
58ab0ad45444e80bdd970ddeb468d0872dbbbb47vboxsync}
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/**
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Gets the name of an address space.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @returns read only address space name.
58ab0ad45444e80bdd970ddeb468d0872dbbbb47vboxsync * NULL if hDbgAs is invalid.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param hDbgAs The address space handle.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @remarks Will not take any locks.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncRTDECL(const char *) RTDbgAsName(RTDBGAS hDbgAs)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync{
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync PRTDBGASINT pDbgAs = hDbgAs;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, NULL);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return pDbgAs->szName;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync}
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/**
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Gets the first address in an address space.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @returns The address.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * 0 if hDbgAs is invalid.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param hDbgAs The address space handle.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @remarks Will not take any locks.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncRTDECL(RTUINTPTR) RTDbgAsFirstAddr(RTDBGAS hDbgAs)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync{
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync PRTDBGASINT pDbgAs = hDbgAs;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, 0);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return pDbgAs->FirstAddr;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync}
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
58ab0ad45444e80bdd970ddeb468d0872dbbbb47vboxsync/**
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Gets the last address in an address space.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @returns The address.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * 0 if hDbgAs is invalid.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param hDbgAs The address space handle.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @remarks Will not take any locks.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncRTDECL(RTUINTPTR) RTDbgAsLastAddr(RTDBGAS hDbgAs)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync{
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync PRTDBGASINT pDbgAs = hDbgAs;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, 0);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return pDbgAs->LastAddr;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync}
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/**
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Gets the number of modules in the address space.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * This can be used together with RTDbgAsModuleByIndex
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * to enumerate the modules.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @returns The number of modules.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param hDbgAs The address space handle.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @remarks Will not take any locks.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncRTDECL(uint32_t) RTDbgAsModuleCount(RTDBGAS hDbgAs)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync{
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync PRTDBGASINT pDbgAs = hDbgAs;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, 0);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return pDbgAs->cModules;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync}
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/**
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Common worker for RTDbgAsModuleLink and RTDbgAsModuleLinkSeg.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @returns IPRT status.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param pDbgAs Pointer to the address space instance data.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param hDbgMod The module to link.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param iSeg The segment to link or NIL if all.
11d3005e2935c925665896fa26fde09b3e656d70vboxsync * @param Addr The address we're linking it at.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param cb The size of what we're linking.
11d3005e2935c925665896fa26fde09b3e656d70vboxsync * @param pszName The name of the module.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param fFlags See RTDBGASLINK_FLAGS_*.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @remarks The caller must have locked the address space for writing.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncint rtDbgAsModuleLinkCommon(PRTDBGASINT pDbgAs, RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg,
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTUINTPTR Addr, RTUINTPTR cb, const char *pszName, uint32_t fFlags)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync{
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /*
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Check that the requested space is undisputed.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync for (;;)
befced03fd84a13590b8ce8be8c2480e9bc568c6vboxsync {
befced03fd84a13590b8ce8be8c2480e9bc568c6vboxsync PRTDBGASMAP pAdjMod = (PRTDBGASMAP)RTAvlrUIntPtrGetBestFit(&pDbgAs->MapTree, Addr, false /* fAbove */);
befced03fd84a13590b8ce8be8c2480e9bc568c6vboxsync if ( pAdjMod
befced03fd84a13590b8ce8be8c2480e9bc568c6vboxsync && pAdjMod->Core.KeyLast >= Addr)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (!(fFlags & RTDBGASLINK_FLAGS_REPLACE))
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return VERR_ADDRESS_CONFLICT;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync rtDbgAsModuleUnlinkByMap(pDbgAs, pAdjMod);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync continue;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync pAdjMod = (PRTDBGASMAP)RTAvlrUIntPtrGetBestFit(&pDbgAs->MapTree, Addr, true /* fAbove */);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if ( pAdjMod
befced03fd84a13590b8ce8be8c2480e9bc568c6vboxsync && pAdjMod->Core.Key >= Addr + cb - 1)
e6a3673a23c632af5208dcc8a37f45d7a20b0554vboxsync {
befced03fd84a13590b8ce8be8c2480e9bc568c6vboxsync if (!(fFlags & RTDBGASLINK_FLAGS_REPLACE))
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return VERR_ADDRESS_CONFLICT;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync rtDbgAsModuleUnlinkByMap(pDbgAs, pAdjMod);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync continue;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync break;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /*
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * First, create or find the module table entry.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync PRTDBGASMOD pMod = (PRTDBGASMOD)RTAvlPVGet(&pDbgAs->ModTree, hDbgMod);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (!pMod)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /*
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Ok, we need a new entry. Grow the table if necessary.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (!(pDbgAs->cModules % 32))
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync void *pvNew = RTMemRealloc(pDbgAs->paModules, sizeof(pDbgAs->paModules[0]) * (pDbgAs->cModules + 32));
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (!pvNew)
befced03fd84a13590b8ce8be8c2480e9bc568c6vboxsync return VERR_NO_MEMORY;
befced03fd84a13590b8ce8be8c2480e9bc568c6vboxsync pDbgAs->paModules = (PRTDBGASMOD)pvNew;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync pMod = &pDbgAs->paModules[pDbgAs->cModules];
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync pDbgAs->cModules++;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync pMod->Core.Key = hDbgMod;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync pMod->pMapHead = NULL;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync pMod->pNextName = NULL;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (!RTAvlPVInsert(&pDbgAs->ModTree, &pMod->Core))
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync AssertFailed();
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync pDbgAs->cModules--;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return VERR_INTERNAL_ERROR;
16d723d9d597f4872dd4c2c960af9cbca4ed63bdvboxsync }
16d723d9d597f4872dd4c2c960af9cbca4ed63bdvboxsync RTDbgModRetain(hDbgMod);
16d723d9d597f4872dd4c2c960af9cbca4ed63bdvboxsync
16d723d9d597f4872dd4c2c960af9cbca4ed63bdvboxsync /*
16d723d9d597f4872dd4c2c960af9cbca4ed63bdvboxsync * Add it to the name space.
16d723d9d597f4872dd4c2c960af9cbca4ed63bdvboxsync */
16d723d9d597f4872dd4c2c960af9cbca4ed63bdvboxsync PRTDBGASNAME pName = (PRTDBGASNAME)RTStrSpaceGet(&pDbgAs->NameSpace, pszName);
16d723d9d597f4872dd4c2c960af9cbca4ed63bdvboxsync if (!pName)
16d723d9d597f4872dd4c2c960af9cbca4ed63bdvboxsync {
16d723d9d597f4872dd4c2c960af9cbca4ed63bdvboxsync size_t cchName = strlen(pszName);
16d723d9d597f4872dd4c2c960af9cbca4ed63bdvboxsync pName = (PRTDBGASNAME)RTMemAlloc(sizeof(*pName) + cchName + 1);
16d723d9d597f4872dd4c2c960af9cbca4ed63bdvboxsync if (!pName)
16d723d9d597f4872dd4c2c960af9cbca4ed63bdvboxsync {
16d723d9d597f4872dd4c2c960af9cbca4ed63bdvboxsync pDbgAs->cModules--;
16d723d9d597f4872dd4c2c960af9cbca4ed63bdvboxsync RTDbgModRelease(hDbgMod);
16d723d9d597f4872dd4c2c960af9cbca4ed63bdvboxsync return VERR_NO_MEMORY;
16d723d9d597f4872dd4c2c960af9cbca4ed63bdvboxsync }
16d723d9d597f4872dd4c2c960af9cbca4ed63bdvboxsync pName->StrCore.cchString = cchName;
16d723d9d597f4872dd4c2c960af9cbca4ed63bdvboxsync pName->StrCore.pszString = (char *)memcpy(pName + 1, pszName, cchName + 1);
79baed6836ae36c5f15b182292387484dcf7a752vboxsync pName->pHead = pMod;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync }
79baed6836ae36c5f15b182292387484dcf7a752vboxsync else
79baed6836ae36c5f15b182292387484dcf7a752vboxsync {
79baed6836ae36c5f15b182292387484dcf7a752vboxsync /* quick, but unfair. */
79baed6836ae36c5f15b182292387484dcf7a752vboxsync pMod->pNextName = pName->pHead;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync pName->pHead = pMod;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync }
79baed6836ae36c5f15b182292387484dcf7a752vboxsync }
79baed6836ae36c5f15b182292387484dcf7a752vboxsync
79baed6836ae36c5f15b182292387484dcf7a752vboxsync /*
79baed6836ae36c5f15b182292387484dcf7a752vboxsync * Create a mapping node.
79baed6836ae36c5f15b182292387484dcf7a752vboxsync */
79baed6836ae36c5f15b182292387484dcf7a752vboxsync int rc;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync PRTDBGASMAP pMap = (PRTDBGASMAP)RTMemAlloc(sizeof(*pMap));
79baed6836ae36c5f15b182292387484dcf7a752vboxsync if (pMap)
79baed6836ae36c5f15b182292387484dcf7a752vboxsync {
79baed6836ae36c5f15b182292387484dcf7a752vboxsync pMap->Core.Key = Addr;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync pMap->Core.KeyLast = Addr + cb - 1;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync pMap->pMod = pMod;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync pMap->iSeg = iSeg;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync if (RTAvlrUIntPtrInsert(&pDbgAs->MapTree, &pMap->Core))
79baed6836ae36c5f15b182292387484dcf7a752vboxsync {
79baed6836ae36c5f15b182292387484dcf7a752vboxsync PRTDBGASMAP *pp = &pMod->pMapHead;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync while (*pp && (*pp)->Core.Key < Addr)
79baed6836ae36c5f15b182292387484dcf7a752vboxsync pp = &(*pp)->pNext;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync pMap->pNext = *pp;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync *pp = pMap;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync return VINF_SUCCESS;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync }
79baed6836ae36c5f15b182292387484dcf7a752vboxsync
79baed6836ae36c5f15b182292387484dcf7a752vboxsync AssertFailed();
79baed6836ae36c5f15b182292387484dcf7a752vboxsync RTMemFree(pMap);
79baed6836ae36c5f15b182292387484dcf7a752vboxsync rc = VERR_ADDRESS_CONFLICT;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync }
79baed6836ae36c5f15b182292387484dcf7a752vboxsync else
79baed6836ae36c5f15b182292387484dcf7a752vboxsync rc = VERR_NO_MEMORY;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync
79baed6836ae36c5f15b182292387484dcf7a752vboxsync /*
79baed6836ae36c5f15b182292387484dcf7a752vboxsync * Unlink the module if this was the only mapping.
79baed6836ae36c5f15b182292387484dcf7a752vboxsync */
79baed6836ae36c5f15b182292387484dcf7a752vboxsync if (!pMod->pMapHead)
79baed6836ae36c5f15b182292387484dcf7a752vboxsync rtDbgAsModuleUnlinkMod(pDbgAs, pMod);
79baed6836ae36c5f15b182292387484dcf7a752vboxsync return rc;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync}
79baed6836ae36c5f15b182292387484dcf7a752vboxsync
79baed6836ae36c5f15b182292387484dcf7a752vboxsync
79baed6836ae36c5f15b182292387484dcf7a752vboxsync/**
79baed6836ae36c5f15b182292387484dcf7a752vboxsync * Links a module into the address space at the give address.
79baed6836ae36c5f15b182292387484dcf7a752vboxsync *
79baed6836ae36c5f15b182292387484dcf7a752vboxsync * The size of the mapping is determined using RTDbgModImageSize().
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @returns IPRT status code.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @retval VERR_OUT_OF_RANGE if the specified address will put the module
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * outside the address space.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @retval VERR_ADDRESS_CONFLICT if the mapping clashes with existing mappings.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param hDbgAs The address space handle.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param hDbgMod The module handle of the module to be linked in.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param ImageAddr The address to link the module at.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param fFlags See RTDBGASLINK_FLAGS_*.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncRTDECL(int) RTDbgAsModuleLink(RTDBGAS hDbgAs, RTDBGMOD hDbgMod, RTUINTPTR ImageAddr, uint32_t fFlags)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync{
11d3005e2935c925665896fa26fde09b3e656d70vboxsync /*
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Validate input.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync PRTDBGASINT pDbgAs = hDbgAs;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, VERR_INVALID_HANDLE);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync const char *pszName = RTDbgModName(hDbgMod);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (!pszName)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return VERR_INVALID_HANDLE;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync RTUINTPTR cb = RTDbgModImageSize(hDbgMod);
79baed6836ae36c5f15b182292387484dcf7a752vboxsync if (!cb)
79baed6836ae36c5f15b182292387484dcf7a752vboxsync return VERR_OUT_OF_RANGE;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync if ( ImageAddr < pDbgAs->FirstAddr
79baed6836ae36c5f15b182292387484dcf7a752vboxsync || ImageAddr > pDbgAs->LastAddr
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync || ImageAddr + cb - 1 < pDbgAs->FirstAddr
69c6eff4fcb6dc027e94a3e7908926c4e8ef5aefvboxsync || ImageAddr + cb - 1 > pDbgAs->LastAddr
69c6eff4fcb6dc027e94a3e7908926c4e8ef5aefvboxsync || ImageAddr + cb - 1 < ImageAddr)
69c6eff4fcb6dc027e94a3e7908926c4e8ef5aefvboxsync return VERR_OUT_OF_RANGE;
69c6eff4fcb6dc027e94a3e7908926c4e8ef5aefvboxsync AssertReturn(!(fFlags & ~RTDBGASLINK_FLAGS_VALID_MASK), VERR_INVALID_PARAMETER);
69c6eff4fcb6dc027e94a3e7908926c4e8ef5aefvboxsync
69c6eff4fcb6dc027e94a3e7908926c4e8ef5aefvboxsync /*
79baed6836ae36c5f15b182292387484dcf7a752vboxsync * Invoke worker common with RTDbgAsModuleLinkSeg.
79baed6836ae36c5f15b182292387484dcf7a752vboxsync */
79baed6836ae36c5f15b182292387484dcf7a752vboxsync RTDBGAS_LOCK_WRITE(pDbgAs);
79baed6836ae36c5f15b182292387484dcf7a752vboxsync int rc = rtDbgAsModuleLinkCommon(pDbgAs, hDbgMod, NIL_RTDBGSEGIDX, ImageAddr, cb, pszName, fFlags);
79baed6836ae36c5f15b182292387484dcf7a752vboxsync RTDBGAS_UNLOCK_WRITE(pDbgAs);
79baed6836ae36c5f15b182292387484dcf7a752vboxsync return rc;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync}
79baed6836ae36c5f15b182292387484dcf7a752vboxsync
79baed6836ae36c5f15b182292387484dcf7a752vboxsync
79baed6836ae36c5f15b182292387484dcf7a752vboxsync/**
79baed6836ae36c5f15b182292387484dcf7a752vboxsync * Links a segment into the address space at the give address.
79baed6836ae36c5f15b182292387484dcf7a752vboxsync *
79baed6836ae36c5f15b182292387484dcf7a752vboxsync * The size of the mapping is determined using RTDbgModSegmentSize().
79baed6836ae36c5f15b182292387484dcf7a752vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @returns IPRT status code.
79baed6836ae36c5f15b182292387484dcf7a752vboxsync * @retval VERR_OUT_OF_RANGE if the specified address will put the module
79baed6836ae36c5f15b182292387484dcf7a752vboxsync * outside the address space.
79baed6836ae36c5f15b182292387484dcf7a752vboxsync * @retval VERR_ADDRESS_CONFLICT if the mapping clashes with existing mappings.
79baed6836ae36c5f15b182292387484dcf7a752vboxsync *
79baed6836ae36c5f15b182292387484dcf7a752vboxsync * @param hDbgAs The address space handle.
79baed6836ae36c5f15b182292387484dcf7a752vboxsync * @param hDbgMod The module handle.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param iSeg The segment number (0-based) of the segment to be
79baed6836ae36c5f15b182292387484dcf7a752vboxsync * linked in.
79baed6836ae36c5f15b182292387484dcf7a752vboxsync * @param SegAddr The address to link the segment at.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param fFlags See RTDBGASLINK_FLAGS_*.
79baed6836ae36c5f15b182292387484dcf7a752vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncRTDECL(int) RTDbgAsModuleLinkSeg(RTDBGAS hDbgAs, RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg, RTUINTPTR SegAddr, uint32_t fFlags)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync{
79baed6836ae36c5f15b182292387484dcf7a752vboxsync /*
79baed6836ae36c5f15b182292387484dcf7a752vboxsync * Validate input.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync PRTDBGASINT pDbgAs = hDbgAs;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, VERR_INVALID_HANDLE);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync const char *pszName = RTDbgModName(hDbgMod);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (!pszName)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return VERR_INVALID_HANDLE;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTUINTPTR cb = RTDbgModSegmentSize(hDbgMod, iSeg);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (!cb)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return VERR_OUT_OF_RANGE;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if ( SegAddr < pDbgAs->FirstAddr
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync || SegAddr > pDbgAs->LastAddr
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync || SegAddr + cb - 1 < pDbgAs->FirstAddr
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync || SegAddr + cb - 1 > pDbgAs->LastAddr
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync || SegAddr + cb - 1 < SegAddr)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return VERR_OUT_OF_RANGE;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync AssertReturn(!(fFlags & ~RTDBGASLINK_FLAGS_VALID_MASK), VERR_INVALID_PARAMETER);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /*
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Invoke worker common with RTDbgAsModuleLinkSeg.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTDBGAS_LOCK_WRITE(pDbgAs);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync int rc = rtDbgAsModuleLinkCommon(pDbgAs, hDbgMod, iSeg, SegAddr, cb, pszName, fFlags);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTDBGAS_UNLOCK_WRITE(pDbgAs);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return rc;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync}
58461e707998a927c19da46b98748ee2b79f4190vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/**
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Worker for RTDbgAsModuleUnlink, RTDbgAsModuleUnlinkByAddr and rtDbgAsModuleLinkCommon.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param pDbgAs Pointer to the address space instance data.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param pMod The module to unlink.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @remarks The caller must have locked the address space for writing.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncstatic void rtDbgAsModuleUnlinkMod(PRTDBGASINT pDbgAs, PRTDBGASMOD pMod)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync{
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync Assert(!pMod->pMapHead);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /*
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Unlink it from the name.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync PRTDBGASNAME pName = (PRTDBGASNAME)RTStrSpaceGet(&pDbgAs->NameSpace, RTDbgModName((RTDBGMOD)pMod->Core.Key));
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync AssertReturnVoid(pName);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (pName->pHead == pMod)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync pName->pHead = pMod->pNextName;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync else
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync for (PRTDBGASMOD pCur = pName->pHead; pCur; pCur = pCur->pNextName)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (pCur->pNextName == pMod)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync pCur->pNextName = pMod->pNextName;
11d3005e2935c925665896fa26fde09b3e656d70vboxsync break;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync pMod->pNextName = NULL;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /*
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Free the name if this was the last reference to it.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (!pName->pHead)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync pName = (PRTDBGASNAME)RTStrSpaceRemove(&pDbgAs->NameSpace, pName->StrCore.pszString);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync Assert(pName);
79baed6836ae36c5f15b182292387484dcf7a752vboxsync RTMemFree(pName);
79baed6836ae36c5f15b182292387484dcf7a752vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /*
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Remove it from the module handle tree.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsync PAVLPVNODECORE pNode = RTAvlPVRemove(&pDbgAs->ModTree, pMod->Core.Key);
27152389a84c6dec057fba6fc21241991e079006vboxsync Assert(pNode == &pMod->Core);
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync /*
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Remove it from the module table by replacing it by the last entry.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsync uint32_t iMod = pMod - &pDbgAs->paModules[0];
27152389a84c6dec057fba6fc21241991e079006vboxsync Assert(iMod < pDbgAs->cModules);
27152389a84c6dec057fba6fc21241991e079006vboxsync pDbgAs->cModules--;
27152389a84c6dec057fba6fc21241991e079006vboxsync if (iMod <= pDbgAs->cModules)
27152389a84c6dec057fba6fc21241991e079006vboxsync pDbgAs->paModules[iMod] = pDbgAs->paModules[pDbgAs->cModules];
27152389a84c6dec057fba6fc21241991e079006vboxsync}
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync/**
27152389a84c6dec057fba6fc21241991e079006vboxsync * Worker for RTDbgAsModuleUnlink and RTDbgAsModuleUnlinkByAddr.
27152389a84c6dec057fba6fc21241991e079006vboxsync *
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param pDbgAs Pointer to the address space instance data.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param pMap The map to unlink and free.
27152389a84c6dec057fba6fc21241991e079006vboxsync *
27152389a84c6dec057fba6fc21241991e079006vboxsync * @remarks The caller must have locked the address space for writing.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsyncstatic void rtDbgAsModuleUnlinkMap(PRTDBGASINT pDbgAs, PRTDBGASMAP pMap)
27152389a84c6dec057fba6fc21241991e079006vboxsync{
27152389a84c6dec057fba6fc21241991e079006vboxsync /* remove from the tree */
27152389a84c6dec057fba6fc21241991e079006vboxsync PAVLRUINTPTRNODECORE pNode = RTAvlrUIntPtrRemove(&pDbgAs->MapTree, pMap->Core.Key);
27152389a84c6dec057fba6fc21241991e079006vboxsync Assert(pNode);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync /* unlink */
27152389a84c6dec057fba6fc21241991e079006vboxsync PRTDBGASMOD pMod = pMap->pMod;
27152389a84c6dec057fba6fc21241991e079006vboxsync if (pMod->pMapHead)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync pMod->pMapHead = pMap->pNext;
27152389a84c6dec057fba6fc21241991e079006vboxsync else
27152389a84c6dec057fba6fc21241991e079006vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync bool fFound = false;
27152389a84c6dec057fba6fc21241991e079006vboxsync for (PRTDBGASMAP pCur = pMod->pMapHead; pCur; pCur = pCur->pNext)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (pCur->pNext == pMap)
27152389a84c6dec057fba6fc21241991e079006vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync pCur->pNext = pMap->pNext;
27152389a84c6dec057fba6fc21241991e079006vboxsync fFound = true;
27152389a84c6dec057fba6fc21241991e079006vboxsync break;
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync Assert(fFound);
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync /* free it */
27152389a84c6dec057fba6fc21241991e079006vboxsync pMap->Core.Key = pMap->Core.KeyLast = 0;
27152389a84c6dec057fba6fc21241991e079006vboxsync pMap->pNext = NULL;
27152389a84c6dec057fba6fc21241991e079006vboxsync pMap->pMod = NULL;
27152389a84c6dec057fba6fc21241991e079006vboxsync RTMemFree(pMap);
27152389a84c6dec057fba6fc21241991e079006vboxsync}
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync/**
27152389a84c6dec057fba6fc21241991e079006vboxsync * Worker for RTDbgAsModuleUnlinkByAddr and rtDbgAsModuleLinkCommon that
27152389a84c6dec057fba6fc21241991e079006vboxsync * unlinks a single mapping and releases the module if it's the last one.
27152389a84c6dec057fba6fc21241991e079006vboxsync *
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param pDbgAs The address space instance.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param pMap The mapping to unlink.
27152389a84c6dec057fba6fc21241991e079006vboxsync *
27152389a84c6dec057fba6fc21241991e079006vboxsync * @remarks The caller must have locked the address space for writing.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsyncstatic void rtDbgAsModuleUnlinkByMap(PRTDBGASINT pDbgAs, PRTDBGASMAP pMap)
27152389a84c6dec057fba6fc21241991e079006vboxsync{
27152389a84c6dec057fba6fc21241991e079006vboxsync /*
27152389a84c6dec057fba6fc21241991e079006vboxsync * Unlink it from the address space.
27152389a84c6dec057fba6fc21241991e079006vboxsync * Unlink the module as well if it's the last mapping it has.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync PRTDBGASMOD pMod = pMap->pMod;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync rtDbgAsModuleUnlinkMap(pDbgAs, pMap);
27152389a84c6dec057fba6fc21241991e079006vboxsync if (!pMod->pMapHead)
27152389a84c6dec057fba6fc21241991e079006vboxsync rtDbgAsModuleUnlinkMod(pDbgAs, pMod);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync}
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync/**
27152389a84c6dec057fba6fc21241991e079006vboxsync * Unlinks all the mappings of a module from the address space.
27152389a84c6dec057fba6fc21241991e079006vboxsync *
27152389a84c6dec057fba6fc21241991e079006vboxsync * @returns IPRT status code.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @retval VERR_NOT_FOUND if the module wasn't found.
27152389a84c6dec057fba6fc21241991e079006vboxsync *
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param hDbgAs The address space handle.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param hDbgMod The module handle of the module to be unlinked.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsyncRTDECL(int) RTDbgAsModuleUnlink(RTDBGAS hDbgAs, RTDBGMOD hDbgMod)
27152389a84c6dec057fba6fc21241991e079006vboxsync{
27152389a84c6dec057fba6fc21241991e079006vboxsync /*
27152389a84c6dec057fba6fc21241991e079006vboxsync * Validate input.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsync PRTDBGASINT pDbgAs = hDbgAs;
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, VERR_INVALID_HANDLE);
27152389a84c6dec057fba6fc21241991e079006vboxsync if (hDbgMod == NIL_RTDBGMOD)
27152389a84c6dec057fba6fc21241991e079006vboxsync return VINF_SUCCESS;
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGAS_LOCK_WRITE(pDbgAs);
27152389a84c6dec057fba6fc21241991e079006vboxsync PRTDBGASMOD pMod = (PRTDBGASMOD)RTAvlPVGet(&pDbgAs->ModTree, hDbgMod);
27152389a84c6dec057fba6fc21241991e079006vboxsync if (!pMod)
27152389a84c6dec057fba6fc21241991e079006vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGAS_UNLOCK_WRITE(pDbgAs);
27152389a84c6dec057fba6fc21241991e079006vboxsync return VERR_NOT_FOUND;
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync /*
27152389a84c6dec057fba6fc21241991e079006vboxsync * Unmap all everything and release the module.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsync while (pMod->pMapHead)
27152389a84c6dec057fba6fc21241991e079006vboxsync rtDbgAsModuleUnlinkMap(pDbgAs, pMod->pMapHead);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync rtDbgAsModuleUnlinkMod(pDbgAs, pMod);
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGAS_UNLOCK_WRITE(pDbgAs);
27152389a84c6dec057fba6fc21241991e079006vboxsync return VINF_SUCCESS;
27152389a84c6dec057fba6fc21241991e079006vboxsync}
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync/**
27152389a84c6dec057fba6fc21241991e079006vboxsync * Unlinks the mapping at the specified address.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
27152389a84c6dec057fba6fc21241991e079006vboxsync * @returns IPRT status code.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @retval VERR_NOT_FOUND if no module or segment is mapped at that address.
27152389a84c6dec057fba6fc21241991e079006vboxsync *
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param hDbgAs The address space handle.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param Addr The address within the mapping to be unlinked.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsyncRTDECL(int) RTDbgAsModuleUnlinkByAddr(RTDBGAS hDbgAs, RTUINTPTR Addr)
27152389a84c6dec057fba6fc21241991e079006vboxsync{
27152389a84c6dec057fba6fc21241991e079006vboxsync /*
27152389a84c6dec057fba6fc21241991e079006vboxsync * Validate input.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync PRTDBGASINT pDbgAs = hDbgAs;
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, VERR_INVALID_HANDLE);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGAS_LOCK_WRITE(pDbgAs);
27152389a84c6dec057fba6fc21241991e079006vboxsync PRTDBGASMAP pMap = (PRTDBGASMAP)RTAvlrUIntPtrRangeGet(&pDbgAs->MapTree, Addr);
27152389a84c6dec057fba6fc21241991e079006vboxsync if (pMap)
27152389a84c6dec057fba6fc21241991e079006vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTDBGAS_UNLOCK_WRITE(pDbgAs);
27152389a84c6dec057fba6fc21241991e079006vboxsync return VERR_NOT_FOUND;
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync /*
27152389a84c6dec057fba6fc21241991e079006vboxsync * Hand it to
27152389a84c6dec057fba6fc21241991e079006vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsync rtDbgAsModuleUnlinkByMap(pDbgAs, pMap);
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGAS_UNLOCK_WRITE(pDbgAs);
27152389a84c6dec057fba6fc21241991e079006vboxsync return VINF_SUCCESS;
27152389a84c6dec057fba6fc21241991e079006vboxsync}
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync/**
27152389a84c6dec057fba6fc21241991e079006vboxsync * Get a the handle of a module in the address space by is index.
27152389a84c6dec057fba6fc21241991e079006vboxsync *
27152389a84c6dec057fba6fc21241991e079006vboxsync * @returns A retained handle to the specified module. The caller must release
27152389a84c6dec057fba6fc21241991e079006vboxsync * the returned reference.
27152389a84c6dec057fba6fc21241991e079006vboxsync * NIL_RTDBGMOD if invalid index or handle.
27152389a84c6dec057fba6fc21241991e079006vboxsync *
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param hDbgAs The address space handle.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param iModule The index of the module to get.
27152389a84c6dec057fba6fc21241991e079006vboxsync *
27152389a84c6dec057fba6fc21241991e079006vboxsync * @remarks The module indexes may change after calls to RTDbgAsModuleLink,
27152389a84c6dec057fba6fc21241991e079006vboxsync * RTDbgAsModuleLinkSeg, RTDbgAsModuleUnlink and
27152389a84c6dec057fba6fc21241991e079006vboxsync * RTDbgAsModuleUnlinkByAddr.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsyncRTDECL(RTDBGMOD) RTDbgAsModuleByIndex(RTDBGAS hDbgAs, uint32_t iModule)
27152389a84c6dec057fba6fc21241991e079006vboxsync{
27152389a84c6dec057fba6fc21241991e079006vboxsync /*
27152389a84c6dec057fba6fc21241991e079006vboxsync * Validate input.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsync PRTDBGASINT pDbgAs = hDbgAs;
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, NIL_RTDBGMOD);
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGAS_LOCK_READ(pDbgAs);
27152389a84c6dec057fba6fc21241991e079006vboxsync if (iModule >= pDbgAs->cModules)
27152389a84c6dec057fba6fc21241991e079006vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGAS_UNLOCK_READ(pDbgAs);
27152389a84c6dec057fba6fc21241991e079006vboxsync return NIL_RTDBGMOD;
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync /*
27152389a84c6dec057fba6fc21241991e079006vboxsync * Get, retain and return it.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGMOD hMod = (RTDBGMOD)pDbgAs->paModules[iModule].Core.Key;
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDbgModRetain(hMod);
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGAS_UNLOCK_READ(pDbgAs);
27152389a84c6dec057fba6fc21241991e079006vboxsync return hMod;
27152389a84c6dec057fba6fc21241991e079006vboxsync}
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync/**
27152389a84c6dec057fba6fc21241991e079006vboxsync * Queries mapping module information by handle.
27152389a84c6dec057fba6fc21241991e079006vboxsync *
27152389a84c6dec057fba6fc21241991e079006vboxsync * @returns IPRT status code.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @retval VERR_NOT_FOUND if no mapping was found at the specified address.
27152389a84c6dec057fba6fc21241991e079006vboxsync *
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param hDbgAs The address space handle.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param Addr Address within the mapping of the module or segment.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param phMod Where to the return the retained module handle.
27152389a84c6dec057fba6fc21241991e079006vboxsync * Optional.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param pAddr Where to return the base address of the mapping.
27152389a84c6dec057fba6fc21241991e079006vboxsync * Optional.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param piSeg Where to return the segment index. This is set to
27152389a84c6dec057fba6fc21241991e079006vboxsync * NIL if the entire module is mapped as a single
79baed6836ae36c5f15b182292387484dcf7a752vboxsync * mapping. Optional.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsyncRTDECL(int) RTDbgAsModuleByAddr(RTDBGAS hDbgAs, RTUINTPTR Addr, PRTDBGMOD phMod, PRTUINTPTR pAddr, PRTDBGSEGIDX piSeg)
27152389a84c6dec057fba6fc21241991e079006vboxsync{
27152389a84c6dec057fba6fc21241991e079006vboxsync /*
27152389a84c6dec057fba6fc21241991e079006vboxsync * Validate input.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
79baed6836ae36c5f15b182292387484dcf7a752vboxsync PRTDBGASINT pDbgAs = hDbgAs;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, VERR_INVALID_HANDLE);
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGAS_LOCK_READ(pDbgAs);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync PRTDBGASMAP pMap = (PRTDBGASMAP)RTAvlrUIntPtrRangeGet(&pDbgAs->MapTree, Addr);
27152389a84c6dec057fba6fc21241991e079006vboxsync if (pMap)
27152389a84c6dec057fba6fc21241991e079006vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGAS_UNLOCK_READ(pDbgAs);
27152389a84c6dec057fba6fc21241991e079006vboxsync return VERR_NOT_FOUND;
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync /*
27152389a84c6dec057fba6fc21241991e079006vboxsync * Set up the return values.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsync if (phMod)
27152389a84c6dec057fba6fc21241991e079006vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGMOD hMod = (RTDBGMOD)pMap->pMod->Core.Key;
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDbgModRetain(hMod);
27152389a84c6dec057fba6fc21241991e079006vboxsync *phMod = hMod;
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync if (pAddr)
27152389a84c6dec057fba6fc21241991e079006vboxsync *pAddr = pMap->Core.Key;
27152389a84c6dec057fba6fc21241991e079006vboxsync if (piSeg)
27152389a84c6dec057fba6fc21241991e079006vboxsync *piSeg = pMap->iSeg;
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGAS_UNLOCK_READ(pDbgAs);
27152389a84c6dec057fba6fc21241991e079006vboxsync return VINF_SUCCESS;
27152389a84c6dec057fba6fc21241991e079006vboxsync}
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync/**
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Queries mapping module information by name.
27152389a84c6dec057fba6fc21241991e079006vboxsync *
27152389a84c6dec057fba6fc21241991e079006vboxsync * @returns IPRT status code.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @retval VERR_NOT_FOUND if no mapping was found at the specified address.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @retval VERR_OUT_OF_RANGE if the name index was out of range.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param hDbgAs The address space handle.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param pszName The module name.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param iName There can be more than one module by the same name
27152389a84c6dec057fba6fc21241991e079006vboxsync * in an address space. This argument indicates which
27152389a84c6dec057fba6fc21241991e079006vboxsync * is ment. (0 based)
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param phMod Where to the return the retained module handle.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsyncRTDECL(int) RTDbgAsModuleByName(RTDBGAS hDbgAs, const char *pszName, uint32_t iName, PRTDBGMOD phMod)
27152389a84c6dec057fba6fc21241991e079006vboxsync{
27152389a84c6dec057fba6fc21241991e079006vboxsync /*
27152389a84c6dec057fba6fc21241991e079006vboxsync * Validate input.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsync PRTDBGASINT pDbgAs = hDbgAs;
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, VERR_INVALID_HANDLE);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync AssertPtrReturn(phMod, VERR_INVALID_POINTER);
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGAS_LOCK_READ(pDbgAs);
27152389a84c6dec057fba6fc21241991e079006vboxsync PRTDBGASNAME pName = (PRTDBGASNAME)RTStrSpaceGet(&pDbgAs->NameSpace, pszName);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (!pName)
27152389a84c6dec057fba6fc21241991e079006vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGAS_UNLOCK_READ(pDbgAs);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return VERR_NOT_FOUND;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync PRTDBGASMOD pMod = pName->pHead;
27152389a84c6dec057fba6fc21241991e079006vboxsync while (iName-- > 0)
27152389a84c6dec057fba6fc21241991e079006vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync pMod = pMod->pNextName;
27152389a84c6dec057fba6fc21241991e079006vboxsync if (!pMod)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGAS_UNLOCK_READ(pDbgAs);
27152389a84c6dec057fba6fc21241991e079006vboxsync return VERR_OUT_OF_RANGE;
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync /*
27152389a84c6dec057fba6fc21241991e079006vboxsync * Get, retain and return it.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGMOD hMod = (RTDBGMOD)pMod->Core.Key;
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDbgModRetain(hMod);
27152389a84c6dec057fba6fc21241991e079006vboxsync *phMod = hMod;
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGAS_UNLOCK_READ(pDbgAs);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return VINF_SUCCESS;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync}
27152389a84c6dec057fba6fc21241991e079006vboxsync
79baed6836ae36c5f15b182292387484dcf7a752vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync/**
27152389a84c6dec057fba6fc21241991e079006vboxsync * Internal worker that looks up and retains a module.
27152389a84c6dec057fba6fc21241991e079006vboxsync *
79baed6836ae36c5f15b182292387484dcf7a752vboxsync * @returns Module handle, NIL_RTDBGMOD if not found.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param pDbgAs The address space instance data.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param Addr Address within the module.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param piSeg where to return the segment index.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param poffSeg Where to return the segment offset.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param pMapAddr The mapping address (RTDBGASMAP::Core.Key).
27152389a84c6dec057fba6fc21241991e079006vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsyncDECLINLINE(RTDBGMOD) rtDbgAsModuleByAddr(PRTDBGASINT pDbgAs, RTUINTPTR Addr, PRTDBGSEGIDX piSeg, PRTUINTPTR poffSeg, PRTUINTPTR pMapAddr)
79baed6836ae36c5f15b182292387484dcf7a752vboxsync{
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGMOD hMod = NIL_RTDBGMOD;
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGAS_LOCK_READ(pDbgAs);
27152389a84c6dec057fba6fc21241991e079006vboxsync PRTDBGASMAP pMap = (PRTDBGASMAP)RTAvlrUIntPtrRangeGet(&pDbgAs->MapTree, Addr);
27152389a84c6dec057fba6fc21241991e079006vboxsync if (pMap)
79baed6836ae36c5f15b182292387484dcf7a752vboxsync {
79baed6836ae36c5f15b182292387484dcf7a752vboxsync hMod = (RTDBGMOD)pMap->pMod->Core.Key;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync RTDbgModRetain(hMod);
79baed6836ae36c5f15b182292387484dcf7a752vboxsync *piSeg = pMap->iSeg != NIL_RTDBGSEGIDX ? pMap->iSeg : RTDBGSEGIDX_RVA;
27152389a84c6dec057fba6fc21241991e079006vboxsync *poffSeg = Addr - pMap->Core.Key;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync if (pMapAddr)
27152389a84c6dec057fba6fc21241991e079006vboxsync *pMapAddr = pMap->Core.Key;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGAS_UNLOCK_READ(pDbgAs);
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync return hMod;
27152389a84c6dec057fba6fc21241991e079006vboxsync}
27152389a84c6dec057fba6fc21241991e079006vboxsync
79baed6836ae36c5f15b182292387484dcf7a752vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync/**
79baed6836ae36c5f15b182292387484dcf7a752vboxsync * Adjusts the address to correspond to the mapping of the module/segment.
27152389a84c6dec057fba6fc21241991e079006vboxsync *
79baed6836ae36c5f15b182292387484dcf7a752vboxsync * @param pSymbol The returned symbol info.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param pMap The mapping record.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param hDbgMod The module handle.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param MapAddr The mapping address.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param iMapSeg The segment that's mapped, NIL_RTDBGSEGIDX or
27152389a84c6dec057fba6fc21241991e079006vboxsync * RTDBGSEGIDX_RVA if the whole module is mapped here.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
79baed6836ae36c5f15b182292387484dcf7a752vboxsyncDECLINLINE(void) rtDbgAsAdjustAddressByMapping(PRTUINTPTR pAddr, RTDBGSEGIDX iSeg,
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGMOD hDbgMod, RTUINTPTR MapAddr, RTDBGSEGIDX iMapSeg)
79baed6836ae36c5f15b182292387484dcf7a752vboxsync{
27152389a84c6dec057fba6fc21241991e079006vboxsync if (iSeg == RTDBGSEGIDX_ABS)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return;
27152389a84c6dec057fba6fc21241991e079006vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (iSeg == RTDBGSEGIDX_RVA)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync if ( iMapSeg == RTDBGSEGIDX_RVA
895d68f6e6c15446ca98b8f6ec96ce19d7ea356fvboxsync || iMapSeg == NIL_RTDBGSEGIDX)
27152389a84c6dec057fba6fc21241991e079006vboxsync *pAddr += MapAddr;
27152389a84c6dec057fba6fc21241991e079006vboxsync else
27152389a84c6dec057fba6fc21241991e079006vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync RTUINTPTR SegRva = RTDbgModSegmentRva(hDbgMod, iMapSeg);
895d68f6e6c15446ca98b8f6ec96ce19d7ea356fvboxsync AssertReturnVoid(SegRva != RTUINTPTR_MAX);
27152389a84c6dec057fba6fc21241991e079006vboxsync AssertMsg(SegRva <= *pAddr, ("SegRva=%RTptr *pAddr=%RTptr\n", SegRva, *pAddr));
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *pAddr += MapAddr - SegRva;
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync else
27152389a84c6dec057fba6fc21241991e079006vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync if ( iMapSeg != RTDBGSEGIDX_RVA
27152389a84c6dec057fba6fc21241991e079006vboxsync && iMapSeg != NIL_RTDBGSEGIDX)
27152389a84c6dec057fba6fc21241991e079006vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync Assert(iMapSeg == iSeg);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *pAddr += MapAddr;
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync else
27152389a84c6dec057fba6fc21241991e079006vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync RTUINTPTR SegRva = RTDbgModSegmentRva(hDbgMod, iSeg);
27152389a84c6dec057fba6fc21241991e079006vboxsync AssertReturnVoid(SegRva != RTUINTPTR_MAX);
27152389a84c6dec057fba6fc21241991e079006vboxsync *pAddr += MapAddr + SegRva;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync}
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync/**
27152389a84c6dec057fba6fc21241991e079006vboxsync * Adjusts the symbol value to correspond to the mapping of the module/segment.
27152389a84c6dec057fba6fc21241991e079006vboxsync *
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param pSymbol The returned symbol info.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param hDbgMod The module handle.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param MapAddr The mapping address.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param iMapSeg The segment that's mapped, NIL_RTDBGSEGIDX if the
27152389a84c6dec057fba6fc21241991e079006vboxsync * whole module is mapped here.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncDECLINLINE(void) rtDbgAsAdjustSymbolValue(PRTDBGSYMBOL pSymbol, RTDBGMOD hDbgMod, RTUINTPTR MapAddr, RTDBGSEGIDX iMapSeg)
27152389a84c6dec057fba6fc21241991e079006vboxsync{
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync Assert(pSymbol->iSeg != NIL_RTDBGSEGIDX);
27152389a84c6dec057fba6fc21241991e079006vboxsync Assert(pSymbol->offSeg == pSymbol->Value);
27152389a84c6dec057fba6fc21241991e079006vboxsync rtDbgAsAdjustAddressByMapping(&pSymbol->Value, pSymbol->iSeg, hDbgMod, MapAddr, iMapSeg);
27152389a84c6dec057fba6fc21241991e079006vboxsync}
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync/**
27152389a84c6dec057fba6fc21241991e079006vboxsync * Adjusts the line number address to correspond to the mapping of the module/segment.
27152389a84c6dec057fba6fc21241991e079006vboxsync *
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param pLine The returned line number info.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param hDbgMod The module handle.
e66911cff9c18da76d9bddb0505ad329a9ccd795vboxsync * @param MapAddr The mapping address.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param iMapSeg The segment that's mapped, NIL_RTDBGSEGIDX if the
27152389a84c6dec057fba6fc21241991e079006vboxsync * whole module is mapped here.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncDECLINLINE(void) rtDbgAsAdjustLineAddress(PRTDBGLINE pLine, RTDBGMOD hDbgMod, RTUINTPTR MapAddr, RTDBGSEGIDX iMapSeg)
27152389a84c6dec057fba6fc21241991e079006vboxsync{
27152389a84c6dec057fba6fc21241991e079006vboxsync Assert(pLine->iSeg != NIL_RTDBGSEGIDX);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync Assert(pLine->offSeg == pLine->Address);
27152389a84c6dec057fba6fc21241991e079006vboxsync rtDbgAsAdjustAddressByMapping(&pLine->Address, pLine->iSeg, hDbgMod, MapAddr, iMapSeg);
27152389a84c6dec057fba6fc21241991e079006vboxsync}
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync/**
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Adds a symbol to a module in the address space.
27152389a84c6dec057fba6fc21241991e079006vboxsync *
27152389a84c6dec057fba6fc21241991e079006vboxsync * @returns IPRT status code. See RTDbgModSymbolAdd for more specific ones.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @retval VERR_INVALID_HANDLE if hDbgAs is invalid.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @retval VERR_NOT_FOUND if no module was found at the specified address.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @retval VERR_NOT_SUPPORTED if the module interpret doesn't support adding
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * custom symbols.
27152389a84c6dec057fba6fc21241991e079006vboxsync *
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param hDbgAs The address space handle.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param pszSymbol The symbol name.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param Addr The address of the symbol.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param cb The size of the symbol.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param fFlags Symbol flags.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsyncRTDECL(int) RTDbgAsSymbolAdd(RTDBGAS hDbgAs, const char *pszSymbol, RTUINTPTR Addr, RTUINTPTR cb, uint32_t fFlags, uint32_t *piOrdinal)
27152389a84c6dec057fba6fc21241991e079006vboxsync{
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /*
27152389a84c6dec057fba6fc21241991e079006vboxsync * Validate input and resolve the address.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync PRTDBGASINT pDbgAs = hDbgAs;
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, VERR_INVALID_HANDLE);
27152389a84c6dec057fba6fc21241991e079006vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTDBGSEGIDX iSeg;
27152389a84c6dec057fba6fc21241991e079006vboxsync RTUINTPTR offSeg;
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGMOD hMod = rtDbgAsModuleByAddr(pDbgAs, Addr, &iSeg, &offSeg, NULL);
27152389a84c6dec057fba6fc21241991e079006vboxsync if (hMod == NIL_RTDBGMOD)
27152389a84c6dec057fba6fc21241991e079006vboxsync return VERR_NOT_FOUND;
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync /*
27152389a84c6dec057fba6fc21241991e079006vboxsync * Forward the call.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsync int rc = RTDbgModSymbolAdd(hMod, pszSymbol, iSeg, offSeg, cb, fFlags, piOrdinal);
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDbgModRelease(hMod);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return rc;
27152389a84c6dec057fba6fc21241991e079006vboxsync}
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync/**
27152389a84c6dec057fba6fc21241991e079006vboxsync * Query a symbol by address.
27152389a84c6dec057fba6fc21241991e079006vboxsync *
895d68f6e6c15446ca98b8f6ec96ce19d7ea356fvboxsync * @returns IPRT status code. See RTDbgModSymbolAddr for more specific ones.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @retval VERR_INVALID_HANDLE if hDbgAs is invalid.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @retval VERR_NOT_FOUND if the address couldn't be mapped to a module.
27152389a84c6dec057fba6fc21241991e079006vboxsync *
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param hDbgAs The address space handle.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param Addr The address which closest symbol is requested.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param poffDisp Where to return the distance between the symbol
27152389a84c6dec057fba6fc21241991e079006vboxsync * and address. Optional.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param pSymbol Where to return the symbol info.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param phMod Where to return the module handle. Optional.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsyncRTDECL(int) RTDbgAsSymbolByAddr(RTDBGAS hDbgAs, RTUINTPTR Addr, PRTINTPTR poffDisp, PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod)
27152389a84c6dec057fba6fc21241991e079006vboxsync{
895d68f6e6c15446ca98b8f6ec96ce19d7ea356fvboxsync /*
27152389a84c6dec057fba6fc21241991e079006vboxsync * Validate input and resolve the address.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
895d68f6e6c15446ca98b8f6ec96ce19d7ea356fvboxsync PRTDBGASINT pDbgAs = hDbgAs;
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, VERR_INVALID_HANDLE);
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGSEGIDX iSeg;
27152389a84c6dec057fba6fc21241991e079006vboxsync RTUINTPTR offSeg;
27152389a84c6dec057fba6fc21241991e079006vboxsync RTUINTPTR MapAddr;
c9a51cded51b8f691f24de730e190ef573344bfcvboxsync RTDBGMOD hMod = rtDbgAsModuleByAddr(pDbgAs, Addr, &iSeg, &offSeg, &MapAddr);
27152389a84c6dec057fba6fc21241991e079006vboxsync if (hMod == NIL_RTDBGMOD)
27152389a84c6dec057fba6fc21241991e079006vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync if (phMod)
27152389a84c6dec057fba6fc21241991e079006vboxsync *phMod = NIL_RTDBGMOD;
27152389a84c6dec057fba6fc21241991e079006vboxsync return VERR_NOT_FOUND;
27152389a84c6dec057fba6fc21241991e079006vboxsync }
c9a51cded51b8f691f24de730e190ef573344bfcvboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync /*
27152389a84c6dec057fba6fc21241991e079006vboxsync * Forward the call.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsync int rc = RTDbgModSymbolByAddr(hMod, iSeg, offSeg, poffDisp, pSymbol);
27152389a84c6dec057fba6fc21241991e079006vboxsync if (RT_SUCCESS(rc))
27152389a84c6dec057fba6fc21241991e079006vboxsync rtDbgAsAdjustSymbolValue(pSymbol, hMod, MapAddr, iSeg);
27152389a84c6dec057fba6fc21241991e079006vboxsync if (phMod)
27152389a84c6dec057fba6fc21241991e079006vboxsync *phMod = hMod;
27152389a84c6dec057fba6fc21241991e079006vboxsync else
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDbgModRelease(hMod);
27152389a84c6dec057fba6fc21241991e079006vboxsync return rc;
27152389a84c6dec057fba6fc21241991e079006vboxsync}
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync/**
27152389a84c6dec057fba6fc21241991e079006vboxsync * Query a symbol by address.
27152389a84c6dec057fba6fc21241991e079006vboxsync *
27152389a84c6dec057fba6fc21241991e079006vboxsync * @returns IPRT status code. See RTDbgModSymbolAddrA for more specific ones.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @retval VERR_INVALID_HANDLE if hDbgAs is invalid.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @retval VERR_NOT_FOUND if the address couldn't be mapped to a module.
27152389a84c6dec057fba6fc21241991e079006vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param hDbgAs The address space handle.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param Addr The address which closest symbol is requested.
ce9015004a47e95eb75e047ba42f2d3200d2d222vboxsync * @param poffDisp Where to return the distance between the symbol
27152389a84c6dec057fba6fc21241991e079006vboxsync * and address. Optional.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param ppSymbol Where to return the pointer to the allocated
27152389a84c6dec057fba6fc21241991e079006vboxsync * symbol info. Always set. Free with RTDbgSymbolFree.
ce9015004a47e95eb75e047ba42f2d3200d2d222vboxsync * @param phMod Where to return the module handle. Optional.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsyncRTDECL(int) RTDbgAsSymbolByAddrA(RTDBGAS hDbgAs, RTUINTPTR Addr, PRTINTPTR poffDisp, PRTDBGSYMBOL *ppSymbol, PRTDBGMOD phMod)
895d68f6e6c15446ca98b8f6ec96ce19d7ea356fvboxsync{
27152389a84c6dec057fba6fc21241991e079006vboxsync /*
ce9015004a47e95eb75e047ba42f2d3200d2d222vboxsync * Validate input and resolve the address.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsync PRTDBGASINT pDbgAs = hDbgAs;
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, VERR_INVALID_HANDLE);
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGSEGIDX iSeg;
27152389a84c6dec057fba6fc21241991e079006vboxsync RTUINTPTR offSeg;
27152389a84c6dec057fba6fc21241991e079006vboxsync RTUINTPTR MapAddr;
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGMOD hMod = rtDbgAsModuleByAddr(pDbgAs, Addr, &iSeg, &offSeg, &MapAddr);
27152389a84c6dec057fba6fc21241991e079006vboxsync if (hMod == NIL_RTDBGMOD)
27152389a84c6dec057fba6fc21241991e079006vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync if (phMod)
27152389a84c6dec057fba6fc21241991e079006vboxsync *phMod = NIL_RTDBGMOD;
27152389a84c6dec057fba6fc21241991e079006vboxsync return VERR_NOT_FOUND;
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync /*
27152389a84c6dec057fba6fc21241991e079006vboxsync * Forward the call.
895d68f6e6c15446ca98b8f6ec96ce19d7ea356fvboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsync int rc = RTDbgModSymbolByAddrA(hMod, iSeg, offSeg, poffDisp, ppSymbol);
895d68f6e6c15446ca98b8f6ec96ce19d7ea356fvboxsync if (RT_SUCCESS(rc))
27152389a84c6dec057fba6fc21241991e079006vboxsync rtDbgAsAdjustSymbolValue(*ppSymbol, hMod, MapAddr, iSeg);
27152389a84c6dec057fba6fc21241991e079006vboxsync if (phMod)
27152389a84c6dec057fba6fc21241991e079006vboxsync *phMod = hMod;
27152389a84c6dec057fba6fc21241991e079006vboxsync else
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDbgModRelease(hMod);
27152389a84c6dec057fba6fc21241991e079006vboxsync return rc;
27152389a84c6dec057fba6fc21241991e079006vboxsync}
27152389a84c6dec057fba6fc21241991e079006vboxsync
895d68f6e6c15446ca98b8f6ec96ce19d7ea356fvboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync/**
27152389a84c6dec057fba6fc21241991e079006vboxsync * Creates a snapshot of the module table on the temporary heap.
27152389a84c6dec057fba6fc21241991e079006vboxsync *
27152389a84c6dec057fba6fc21241991e079006vboxsync * The caller must release all the module handles before freeing the table
27152389a84c6dec057fba6fc21241991e079006vboxsync * using RTMemTmpFree.
27152389a84c6dec057fba6fc21241991e079006vboxsync *
27152389a84c6dec057fba6fc21241991e079006vboxsync * @returns Module table snaphot.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param pDbgAs The address space instance data.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param pcModules Where to return the number of modules.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsyncDECLINLINE(PRTDBGMOD) rtDbgAsSnapshotModuleTable(PRTDBGASINT pDbgAs, uint32_t *pcModules)
27152389a84c6dec057fba6fc21241991e079006vboxsync{
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGAS_LOCK_READ(pDbgAs);
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync uint32_t iMod = *pcModules = pDbgAs->cModules;
27152389a84c6dec057fba6fc21241991e079006vboxsync PRTDBGMOD paModules = (PRTDBGMOD)RTMemTmpAlloc(sizeof(paModules[0]) * RT_MAX(iMod, 1));
27152389a84c6dec057fba6fc21241991e079006vboxsync if (paModules)
27152389a84c6dec057fba6fc21241991e079006vboxsync {
895d68f6e6c15446ca98b8f6ec96ce19d7ea356fvboxsync while (iMod-- > 0)
27152389a84c6dec057fba6fc21241991e079006vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGMOD hMod = (RTDBGMOD)pDbgAs->paModules[iMod].Core.Key;
c9a51cded51b8f691f24de730e190ef573344bfcvboxsync paModules[iMod] = hMod;
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDbgModRetain(hMod);
27152389a84c6dec057fba6fc21241991e079006vboxsync }
c9a51cded51b8f691f24de730e190ef573344bfcvboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGAS_UNLOCK_READ(pDbgAs);
27152389a84c6dec057fba6fc21241991e079006vboxsync return paModules;
27152389a84c6dec057fba6fc21241991e079006vboxsync}
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync/**
27152389a84c6dec057fba6fc21241991e079006vboxsync * Attempts to find a mapping of the specified symbol/module and
27152389a84c6dec057fba6fc21241991e079006vboxsync * adjust it's Value field accordingly.
27152389a84c6dec057fba6fc21241991e079006vboxsync *
27152389a84c6dec057fba6fc21241991e079006vboxsync * @returns true / false success indicator.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param pDbgAs The address space.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param hDbgMod The module handle.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param pSymbol The symbol info.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsyncstatic bool rtDbgAsFindMappingAndAdjustSymbolValue(PRTDBGASINT pDbgAs, RTDBGMOD hDbgMod, PRTDBGSYMBOL pSymbol)
27152389a84c6dec057fba6fc21241991e079006vboxsync{
27152389a84c6dec057fba6fc21241991e079006vboxsync /*
27152389a84c6dec057fba6fc21241991e079006vboxsync * Absolute segments needs no fixing.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGSEGIDX const iSeg = pSymbol->iSeg;
27152389a84c6dec057fba6fc21241991e079006vboxsync if (iSeg)
27152389a84c6dec057fba6fc21241991e079006vboxsync return true;
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGAS_LOCK_READ(pDbgAs);
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync /*
27152389a84c6dec057fba6fc21241991e079006vboxsync * Lookup up the module by it's handle and iterate the mappings looking for one
27152389a84c6dec057fba6fc21241991e079006vboxsync * that either encompasses the entire module or the segment in question.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
5558d00238c7e019ef8c0803358fae6edeba394evboxsync PRTDBGASMOD pMod = (PRTDBGASMOD)RTAvlPVGet(&pDbgAs->ModTree, hDbgMod);
5558d00238c7e019ef8c0803358fae6edeba394evboxsync if (pMod)
5558d00238c7e019ef8c0803358fae6edeba394evboxsync {
5558d00238c7e019ef8c0803358fae6edeba394evboxsync for (PRTDBGASMAP pMap = pMod->pMapHead; pMap; pMap = pMap->pNext)
5558d00238c7e019ef8c0803358fae6edeba394evboxsync {
5558d00238c7e019ef8c0803358fae6edeba394evboxsync /* Exact segment match or full-mapping. */
5558d00238c7e019ef8c0803358fae6edeba394evboxsync if ( iSeg == pMap->iSeg
27152389a84c6dec057fba6fc21241991e079006vboxsync || pMap->iSeg == NIL_RTDBGSEGIDX)
27152389a84c6dec057fba6fc21241991e079006vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync RTUINTPTR MapAddr = pMap->Core.Key;
5558d00238c7e019ef8c0803358fae6edeba394evboxsync RTDBGSEGIDX iMapSeg = pMap->iSeg;
27152389a84c6dec057fba6fc21241991e079006vboxsync
ce9015004a47e95eb75e047ba42f2d3200d2d222vboxsync RTDBGAS_UNLOCK_READ(pDbgAs);
27152389a84c6dec057fba6fc21241991e079006vboxsync rtDbgAsAdjustSymbolValue(pSymbol, hDbgMod, MapAddr, iMapSeg);
27152389a84c6dec057fba6fc21241991e079006vboxsync return true;
ce9015004a47e95eb75e047ba42f2d3200d2d222vboxsync }
ce9015004a47e95eb75e047ba42f2d3200d2d222vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync /* Symbol uses RVA and the mapping doesn't, see if it's in the mapped segment. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (iSeg == RTDBGSEGIDX_RVA)
27152389a84c6dec057fba6fc21241991e079006vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync Assert(pMap->iSeg != NIL_RTDBGSEGIDX);
27152389a84c6dec057fba6fc21241991e079006vboxsync RTUINTPTR SegRva = RTDbgModSegmentRva(hDbgMod, pMap->iSeg);
27152389a84c6dec057fba6fc21241991e079006vboxsync Assert(SegRva != RTUINTPTR_MAX);
27152389a84c6dec057fba6fc21241991e079006vboxsync RTUINTPTR cbSeg = RTDbgModSegmentSize(hDbgMod, pMap->iSeg);
27152389a84c6dec057fba6fc21241991e079006vboxsync if (SegRva - pSymbol->Value < cbSeg)
27152389a84c6dec057fba6fc21241991e079006vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTUINTPTR MapAddr = pMap->Core.Key;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTDBGSEGIDX iMapSeg = pMap->iSeg;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGAS_UNLOCK_READ(pDbgAs);
27152389a84c6dec057fba6fc21241991e079006vboxsync rtDbgAsAdjustSymbolValue(pSymbol, hDbgMod, MapAddr, iMapSeg);
27152389a84c6dec057fba6fc21241991e079006vboxsync return true;
27152389a84c6dec057fba6fc21241991e079006vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync }
895d68f6e6c15446ca98b8f6ec96ce19d7ea356fvboxsync /* else: Unmapped while we were searching. */
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGAS_UNLOCK_READ(pDbgAs);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return false;
27152389a84c6dec057fba6fc21241991e079006vboxsync}
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync/**
27152389a84c6dec057fba6fc21241991e079006vboxsync * Query a symbol by name.
27152389a84c6dec057fba6fc21241991e079006vboxsync *
27152389a84c6dec057fba6fc21241991e079006vboxsync * @returns IPRT status code.
895d68f6e6c15446ca98b8f6ec96ce19d7ea356fvboxsync * @retval VERR_SYMBOL_NOT_FOUND if not found.
27152389a84c6dec057fba6fc21241991e079006vboxsync *
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param hDbgAs The address space handle.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param pszSymbol The symbol name. It is possible to limit the scope
27152389a84c6dec057fba6fc21241991e079006vboxsync * of the search by prefixing the symbol with a module
895d68f6e6c15446ca98b8f6ec96ce19d7ea356fvboxsync * name pattern followed by a bang (!) character.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * RTStrSimplePatternNMatch is used for the matching.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param pSymbol Where to return the symbol info.
c9a51cded51b8f691f24de730e190ef573344bfcvboxsync * @param phMod Where to return the module handle. Optional.
c9a51cded51b8f691f24de730e190ef573344bfcvboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncRTDECL(int) RTDbgAsSymbolByName(RTDBGAS hDbgAs, const char *pszSymbol, PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync{
27152389a84c6dec057fba6fc21241991e079006vboxsync /*
3425990d4ff653d1e1c5a5b909cc5a095a3bd2d8vboxsync * Validate input.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsync PRTDBGASINT pDbgAs = hDbgAs;
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, VERR_INVALID_HANDLE);
27152389a84c6dec057fba6fc21241991e079006vboxsync AssertPtrReturn(pszSymbol, VERR_INVALID_POINTER);
27152389a84c6dec057fba6fc21241991e079006vboxsync AssertPtrReturn(pSymbol, VERR_INVALID_POINTER);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /*
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Look for module pattern.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
f5b7890acb8ed84648facc56aa99ef3c6dbf90c7vboxsync const char *pachModPat = NULL;
27152389a84c6dec057fba6fc21241991e079006vboxsync size_t cchModPat = 0;
27152389a84c6dec057fba6fc21241991e079006vboxsync const char *pszBang = strchr(pszSymbol, '!');
27152389a84c6dec057fba6fc21241991e079006vboxsync if (pszBang)
27152389a84c6dec057fba6fc21241991e079006vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync pachModPat = pszSymbol;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync cchModPat = pszBang - pszSymbol;
27152389a84c6dec057fba6fc21241991e079006vboxsync pszSymbol = pszBang + 1;
27152389a84c6dec057fba6fc21241991e079006vboxsync if (!*pszSymbol)
27152389a84c6dec057fba6fc21241991e079006vboxsync return VERR_DBG_SYMBOL_NAME_OUT_OF_RANGE;
27152389a84c6dec057fba6fc21241991e079006vboxsync /* Note! Zero length module -> no pattern -> escape for symbol with '!'. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync /*
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Iterate the modules, looking for the symbol.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync uint32_t cModules;
27152389a84c6dec057fba6fc21241991e079006vboxsync PRTDBGMOD paModules = rtDbgAsSnapshotModuleTable(pDbgAs, &cModules);
27152389a84c6dec057fba6fc21241991e079006vboxsync if (!paModules)
27152389a84c6dec057fba6fc21241991e079006vboxsync return VERR_NO_TMP_MEMORY;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync for (uint32_t i = 0; i < cModules; i++)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync if ( cchModPat == 0
27152389a84c6dec057fba6fc21241991e079006vboxsync || RTStrSimplePatternNMatch(pachModPat, cchModPat, RTDbgModName(paModules[i]), RTSTR_MAX))
27152389a84c6dec057fba6fc21241991e079006vboxsync {
85e5ab5adbba74b522731762dd05ca88cb529140vboxsync int rc = RTDbgModSymbolByName(paModules[i], pszSymbol, pSymbol);
27152389a84c6dec057fba6fc21241991e079006vboxsync if (RT_SUCCESS(rc))
27152389a84c6dec057fba6fc21241991e079006vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (rtDbgAsFindMappingAndAdjustSymbolValue(pDbgAs, paModules[i], pSymbol))
27152389a84c6dec057fba6fc21241991e079006vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync if (phMod)
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDbgModRetain(*phMod = paModules[i]);
27152389a84c6dec057fba6fc21241991e079006vboxsync for (; i < cModules; i++)
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDbgModRelease(paModules[i]);
27152389a84c6dec057fba6fc21241991e079006vboxsync RTMemTmpFree(paModules);
27152389a84c6dec057fba6fc21241991e079006vboxsync return rc;
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDbgModRelease(paModules[i]);
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync RTMemTmpFree(paModules);
27152389a84c6dec057fba6fc21241991e079006vboxsync return VERR_SYMBOL_NOT_FOUND;
27152389a84c6dec057fba6fc21241991e079006vboxsync}
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync/**
27152389a84c6dec057fba6fc21241991e079006vboxsync * Query a symbol by name, allocating the returned symbol structure.
27152389a84c6dec057fba6fc21241991e079006vboxsync *
27152389a84c6dec057fba6fc21241991e079006vboxsync * @returns IPRT status code.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @retval VERR_SYMBOL_NOT_FOUND if not found.
27152389a84c6dec057fba6fc21241991e079006vboxsync *
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param hDbgAs The address space handle.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param pszSymbol The symbol name. See RTDbgAsSymbolByName for more.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param ppSymbol Where to return the pointer to the allocated
27152389a84c6dec057fba6fc21241991e079006vboxsync * symbol info. Always set. Free with RTDbgSymbolFree.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param phMod Where to return the module handle. Optional.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsyncRTDECL(int) RTDbgAsSymbolByNameA(RTDBGAS hDbgAs, const char *pszSymbol, PRTDBGSYMBOL *ppSymbol, PRTDBGMOD phMod)
27152389a84c6dec057fba6fc21241991e079006vboxsync{
27152389a84c6dec057fba6fc21241991e079006vboxsync /*
27152389a84c6dec057fba6fc21241991e079006vboxsync * Validate input.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsync AssertPtrReturn(ppSymbol, VERR_INVALID_POINTER);
27152389a84c6dec057fba6fc21241991e079006vboxsync *ppSymbol = NULL;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync PRTDBGASINT pDbgAs = hDbgAs;
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, VERR_INVALID_HANDLE);
27152389a84c6dec057fba6fc21241991e079006vboxsync AssertPtrReturn(pszSymbol, VERR_INVALID_POINTER);
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync /*
27152389a84c6dec057fba6fc21241991e079006vboxsync * Look for module pattern.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsync const char *pachModPat = NULL;
27152389a84c6dec057fba6fc21241991e079006vboxsync size_t cchModPat = 0;
27152389a84c6dec057fba6fc21241991e079006vboxsync const char *pszBang = strchr(pszSymbol, '!');
27152389a84c6dec057fba6fc21241991e079006vboxsync if (pszBang)
27152389a84c6dec057fba6fc21241991e079006vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync pachModPat = pszSymbol;
27152389a84c6dec057fba6fc21241991e079006vboxsync cchModPat = pszBang - pszSymbol;
27152389a84c6dec057fba6fc21241991e079006vboxsync pszSymbol = pszBang + 1;
27152389a84c6dec057fba6fc21241991e079006vboxsync if (!*pszSymbol)
27152389a84c6dec057fba6fc21241991e079006vboxsync return VERR_DBG_SYMBOL_NAME_OUT_OF_RANGE;
27152389a84c6dec057fba6fc21241991e079006vboxsync /* Note! Zero length module -> no pattern -> escape for symbol with '!'. */
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync /*
27152389a84c6dec057fba6fc21241991e079006vboxsync * Iterate the modules, looking for the symbol.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsync uint32_t cModules;
27152389a84c6dec057fba6fc21241991e079006vboxsync PRTDBGMOD paModules = rtDbgAsSnapshotModuleTable(pDbgAs, &cModules);
27152389a84c6dec057fba6fc21241991e079006vboxsync if (!paModules)
27152389a84c6dec057fba6fc21241991e079006vboxsync return VERR_NO_TMP_MEMORY;
27152389a84c6dec057fba6fc21241991e079006vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync for (uint32_t i = 0; i < cModules; i++)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync if ( cchModPat == 0
27152389a84c6dec057fba6fc21241991e079006vboxsync || RTStrSimplePatternNMatch(pachModPat, cchModPat, RTDbgModName(paModules[i]), RTSTR_MAX))
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync int rc = RTDbgModSymbolByNameA(paModules[i], pszSymbol, ppSymbol);
27152389a84c6dec057fba6fc21241991e079006vboxsync if (RT_SUCCESS(rc))
27152389a84c6dec057fba6fc21241991e079006vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync if (rtDbgAsFindMappingAndAdjustSymbolValue(pDbgAs, paModules[i], *ppSymbol))
27152389a84c6dec057fba6fc21241991e079006vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync if (phMod)
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDbgModRetain(*phMod = paModules[i]);
27152389a84c6dec057fba6fc21241991e079006vboxsync for (; i < cModules; i++)
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDbgModRelease(paModules[i]);
27152389a84c6dec057fba6fc21241991e079006vboxsync RTMemTmpFree(paModules);
27152389a84c6dec057fba6fc21241991e079006vboxsync return rc;
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDbgModRelease(paModules[i]);
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync RTMemTmpFree(paModules);
85e5ab5adbba74b522731762dd05ca88cb529140vboxsync return VERR_SYMBOL_NOT_FOUND;
27152389a84c6dec057fba6fc21241991e079006vboxsync}
27152389a84c6dec057fba6fc21241991e079006vboxsync
85e5ab5adbba74b522731762dd05ca88cb529140vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync/**
85e5ab5adbba74b522731762dd05ca88cb529140vboxsync * Adds a line number to a module in the address space.
27152389a84c6dec057fba6fc21241991e079006vboxsync *
27152389a84c6dec057fba6fc21241991e079006vboxsync * @returns IPRT status code. See RTDbgModSymbolAdd for more specific ones.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @retval VERR_INVALID_HANDLE if hDbgAs is invalid.
85e5ab5adbba74b522731762dd05ca88cb529140vboxsync * @retval VERR_NOT_FOUND if no module was found at the specified address.
85e5ab5adbba74b522731762dd05ca88cb529140vboxsync * @retval VERR_NOT_SUPPORTED if the module interpret doesn't support adding
85e5ab5adbba74b522731762dd05ca88cb529140vboxsync * custom symbols.
27152389a84c6dec057fba6fc21241991e079006vboxsync *
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param hDbgAs The address space handle.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param pszFile The file name.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param uLineNo The line number.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param Addr The address of the symbol.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param piOrdinal Where to return the line number ordinal on success.
27152389a84c6dec057fba6fc21241991e079006vboxsync * If the interpreter doesn't do ordinals, this will be
5558d00238c7e019ef8c0803358fae6edeba394evboxsync * set to UINT32_MAX. Optional.
5558d00238c7e019ef8c0803358fae6edeba394evboxsync */
5558d00238c7e019ef8c0803358fae6edeba394evboxsyncRTDECL(int) RTDbgAsLineAdd(RTDBGAS hDbgAs, const char *pszFile, uint32_t uLineNo, RTUINTPTR Addr, uint32_t *piOrdinal)
5558d00238c7e019ef8c0803358fae6edeba394evboxsync{
5558d00238c7e019ef8c0803358fae6edeba394evboxsync /*
5558d00238c7e019ef8c0803358fae6edeba394evboxsync * Validate input and resolve the address.
5558d00238c7e019ef8c0803358fae6edeba394evboxsync */
5558d00238c7e019ef8c0803358fae6edeba394evboxsync PRTDBGASINT pDbgAs = hDbgAs;
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, VERR_INVALID_HANDLE);
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGSEGIDX iSeg;
27152389a84c6dec057fba6fc21241991e079006vboxsync RTUINTPTR offSeg;
85e5ab5adbba74b522731762dd05ca88cb529140vboxsync RTDBGMOD hMod = rtDbgAsModuleByAddr(pDbgAs, Addr, &iSeg, &offSeg, NULL);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (hMod == NIL_RTDBGMOD)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return VERR_NOT_FOUND;
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync /*
27152389a84c6dec057fba6fc21241991e079006vboxsync * Forward the call.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync int rc = RTDbgModLineAdd(hMod, pszFile, uLineNo, iSeg, offSeg, piOrdinal);
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDbgModRelease(hMod);
27152389a84c6dec057fba6fc21241991e079006vboxsync return rc;
27152389a84c6dec057fba6fc21241991e079006vboxsync}
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync
85e5ab5adbba74b522731762dd05ca88cb529140vboxsync/**
27152389a84c6dec057fba6fc21241991e079006vboxsync * Query a line number by address.
27152389a84c6dec057fba6fc21241991e079006vboxsync *
27152389a84c6dec057fba6fc21241991e079006vboxsync * @returns IPRT status code. See RTDbgModSymbolAddrA for more specific ones.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @retval VERR_INVALID_HANDLE if hDbgAs is invalid.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @retval VERR_NOT_FOUND if the address couldn't be mapped to a module.
27152389a84c6dec057fba6fc21241991e079006vboxsync *
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param hDbgAs The address space handle.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param Addr The address which closest symbol is requested.
85e5ab5adbba74b522731762dd05ca88cb529140vboxsync * @param poffDisp Where to return the distance between the line
27152389a84c6dec057fba6fc21241991e079006vboxsync * number and address.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param pLine Where to return the line number information.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsyncRTDECL(int) RTDbgAsLineByAddr(RTDBGAS hDbgAs, RTUINTPTR Addr, PRTINTPTR poffDisp, PRTDBGLINE pLine)
27152389a84c6dec057fba6fc21241991e079006vboxsync{
27152389a84c6dec057fba6fc21241991e079006vboxsync /*
27152389a84c6dec057fba6fc21241991e079006vboxsync * Validate input and resolve the address.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync PRTDBGASINT pDbgAs = hDbgAs;
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, VERR_INVALID_HANDLE);
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDBGSEGIDX iSeg;
27152389a84c6dec057fba6fc21241991e079006vboxsync RTUINTPTR offSeg;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTUINTPTR MapAddr;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTDBGMOD hMod = rtDbgAsModuleByAddr(pDbgAs, Addr, &iSeg, &offSeg, &MapAddr);
27152389a84c6dec057fba6fc21241991e079006vboxsync if (hMod == NIL_RTDBGMOD)
27152389a84c6dec057fba6fc21241991e079006vboxsync return VERR_NOT_FOUND;
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync /*
27152389a84c6dec057fba6fc21241991e079006vboxsync * Forward the call.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsync int rc = RTDbgModLineByAddr(hMod, iSeg, offSeg, poffDisp, pLine);
27152389a84c6dec057fba6fc21241991e079006vboxsync if (RT_SUCCESS(rc))
27152389a84c6dec057fba6fc21241991e079006vboxsync rtDbgAsAdjustLineAddress(pLine, hMod, MapAddr, iSeg);
27152389a84c6dec057fba6fc21241991e079006vboxsync RTDbgModRelease(hMod);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return rc;
27152389a84c6dec057fba6fc21241991e079006vboxsync}
27152389a84c6dec057fba6fc21241991e079006vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync/**
27152389a84c6dec057fba6fc21241991e079006vboxsync * Query a line number by address.
27152389a84c6dec057fba6fc21241991e079006vboxsync *
27152389a84c6dec057fba6fc21241991e079006vboxsync * @returns IPRT status code. See RTDbgModSymbolAddrA for more specific ones.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @retval VERR_INVALID_HANDLE if hDbgAs is invalid.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @retval VERR_NOT_FOUND if the address couldn't be mapped to a module.
27152389a84c6dec057fba6fc21241991e079006vboxsync *
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param hDbgAs The address space handle.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param Addr The address which closest symbol is requested.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param poffDisp Where to return the distance between the line
27152389a84c6dec057fba6fc21241991e079006vboxsync * number and address.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param ppLine Where to return the pointer to the allocated line
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * number info. Always set. Free with RTDbgLineFree.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncRTDECL(int) RTDbgAsLineByAddrA(RTDBGAS hDbgAs, RTUINTPTR Addr, PRTINTPTR poffDisp, PRTDBGLINE *ppLine)
27152389a84c6dec057fba6fc21241991e079006vboxsync{
27152389a84c6dec057fba6fc21241991e079006vboxsync /*
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Validate input and resolve the address.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync PRTDBGASINT pDbgAs = hDbgAs;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTDBGAS_VALID_RETURN_RC(pDbgAs, VERR_INVALID_HANDLE);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
6370aaf3748669b056c6ede9b64ff5f837a17820vboxsync RTDBGSEGIDX iSeg;
6370aaf3748669b056c6ede9b64ff5f837a17820vboxsync RTUINTPTR offSeg;
6370aaf3748669b056c6ede9b64ff5f837a17820vboxsync RTUINTPTR MapAddr;
6370aaf3748669b056c6ede9b64ff5f837a17820vboxsync RTDBGMOD hMod = rtDbgAsModuleByAddr(pDbgAs, Addr, &iSeg, &offSeg, &MapAddr);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (hMod == NIL_RTDBGMOD)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return VERR_NOT_FOUND;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /*
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Forward the call.
e50527359fb17a5127ef6291e691c8f09d726157vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync int rc = RTDbgModLineByAddrA(hMod, iSeg, offSeg, poffDisp, ppLine);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (RT_SUCCESS(rc))
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync rtDbgAsAdjustLineAddress(*ppLine, hMod, MapAddr, iSeg);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTDbgModRelease(hMod);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return rc;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync}
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync