diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-11 08:17:27 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-11 08:17:27 +0000 |
commit | f215e02bf85f68d3a6106c2a1f4f7f063f819064 (patch) | |
tree | 6bb5b92c046312c4e95ac2620b10ddf482d3fa8b /src/VBox/Runtime/include | |
parent | Initial commit. (diff) | |
download | virtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.tar.xz virtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.zip |
Adding upstream version 7.0.14-dfsg.upstream/7.0.14-dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/VBox/Runtime/include')
35 files changed, 6189 insertions, 0 deletions
diff --git a/src/VBox/Runtime/include/internal/alignmentchecks.h b/src/VBox/Runtime/include/internal/alignmentchecks.h new file mode 100644 index 00000000..99573d42 --- /dev/null +++ b/src/VBox/Runtime/include/internal/alignmentchecks.h @@ -0,0 +1,84 @@ +/* $Id: alignmentchecks.h $ */ +/** @file + * IPRT - Internal header for hacking alignment checks on x86 and AMD64. + */ + +/* + * Copyright (C) 2009-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_INTERNAL_alignmentchecks_h +#define IPRT_INCLUDED_INTERNAL_alignmentchecks_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +/** @def IPRT_WITH_ALIGNMENT_CHECKS + * Enables or disables the alignment check feature and related hacks. */ + +#ifndef IPRT_WITH_ALIGNMENT_CHECKS +# if ( defined(DEBUG) && !defined(IN_GUEST) ) || defined(DOXYGEN_RUNNING) +# define IPRT_WITH_ALIGNMENT_CHECKS 1 +# endif +#endif + +/** @def IPRT_ALIGNMENT_CHECKS_DISABLE + * Disables alignment checks. + * Typically used before calling problematic library functions. + */ + +/** @def IPRT_ALIGNMENT_CHECKS_ENABLE + * (re-)Enables alignment checks if they are supposed to be active. + * This is used to counter IPRT_ALIGNMENT_CHECKS_DISABLE as well as enabling + * them for the first time. + */ + +#if defined(IPRT_WITH_ALIGNMENT_CHECKS) \ + && ( defined(RT_ARCH_AMD64) \ + || defined(RT_ARCH_X86) ) +# include <iprt/asm-amd64-x86.h> + +RT_C_DECLS_BEGIN +extern RTDATADECL(bool) g_fRTAlignmentChecks; +RT_C_DECLS_END + +# define IPRT_ALIGNMENT_CHECKS_DISABLE() \ + do { if (g_fRTAlignmentChecks) ASMSetFlags(ASMGetFlags() & ~RT_BIT_32(18)); } while (0) + +# define IPRT_ALIGNMENT_CHECKS_ENABLE() \ + do { if (g_fRTAlignmentChecks) ASMSetFlags(ASMGetFlags() | RT_BIT_32(18)); } while (0) + +#else +# define IPRT_ALIGNMENT_CHECKS_DISABLE() do {} while (0) +# define IPRT_ALIGNMENT_CHECKS_ENABLE() do {} while (0) +#endif + +#endif /* !IPRT_INCLUDED_INTERNAL_alignmentchecks_h */ + diff --git a/src/VBox/Runtime/include/internal/assert.h b/src/VBox/Runtime/include/internal/assert.h new file mode 100644 index 00000000..93013cd4 --- /dev/null +++ b/src/VBox/Runtime/include/internal/assert.h @@ -0,0 +1,76 @@ +/* $Id: assert.h $ */ +/** @file + * IPRT - Internal RTAssert header + */ + +/* + * Copyright (C) 2009-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_INTERNAL_assert_h +#define IPRT_INCLUDED_INTERNAL_assert_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/types.h> + +RT_C_DECLS_BEGIN + +#ifdef IN_RING0 + +/** + * Print the 1st part of an assert message to whatever native facility is best + * fitting. + * + * @param pszExpr Expression. Can be NULL. + * @param uLine Location line number. + * @param pszFile Location file name. + * @param pszFunction Location function name. + */ +DECLHIDDEN(void) rtR0AssertNativeMsg1(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction); + +/** + * Print the 2nd (optional) part of an assert message to whatever native + * facility is best fitting. + * + * @param fInitial Whether it's the initial (true) or an additional (false) + * message. + * @param pszFormat Printf like format string. + * @param va Arguments to that string. + */ +DECLHIDDEN(void) rtR0AssertNativeMsg2V(bool fInitial, const char *pszFormat, va_list va); + +#endif + +RT_C_DECLS_END + +#endif /* !IPRT_INCLUDED_INTERNAL_assert_h */ + diff --git a/src/VBox/Runtime/include/internal/bignum.mac b/src/VBox/Runtime/include/internal/bignum.mac new file mode 100644 index 00000000..45a86693 --- /dev/null +++ b/src/VBox/Runtime/include/internal/bignum.mac @@ -0,0 +1,64 @@ +; $Id: bignum.mac $ +;; @file +; IPRT - Internal RTAssert header +; + +; +; Copyright (C) 2009-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +%ifndef ___internal_bignum_mac___ +%define ___internal_bignum_mac___ + +%include "iprt/asmdefs.mac" + + +%if ARCH_BITS == 64 + %define RTBIGNUM_ELEMENT_SIZE 8 + %define RTBIGNUM_ELEMENT_BITS (RTBIGNUM_ELEMENT_SIZE * 8) + %define RTBIGNUM_ELEMENT_BIT(iBit) RT_BIT_64(iBit) + %define RTBIGNUM_ELEMENT_PRE qword +%else + %define RTBIGNUM_ELEMENT_SIZE 4 + %define RTBIGNUM_ELEMENT_BITS (RTBIGNUM_ELEMENT_SIZE * 8) + %define RTBIGNUM_ELEMENT_BIT(iBit) RT_BIT_32(iBit) + %define RTBIGNUM_ELEMENT_PRE dword +%endif + +struc RTBIGNUM + .pauElements RTCCPTR_RES 1 + .cUsed resd 1 + .cAllocated resd 1 + .uReserved resd 1 + .fFlags resd 1 +endstruc + +%endif + diff --git a/src/VBox/Runtime/include/internal/compiler-vcc.h b/src/VBox/Runtime/include/internal/compiler-vcc.h new file mode 100644 index 00000000..98a4b7aa --- /dev/null +++ b/src/VBox/Runtime/include/internal/compiler-vcc.h @@ -0,0 +1,155 @@ +/* $Id: compiler-vcc.h $ */ +/** @file + * IPRT - Internal header for the Visual C++ Compiler Support Code. + */ + +/* + * Copyright (C) 2022-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_INTERNAL_compiler_vcc_h +#define IPRT_INCLUDED_INTERNAL_compiler_vcc_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/types.h> + +/** @name Special sections. + * @{ + */ + +#ifdef IPRT_COMPILER_VCC_WITH_C_INIT_TERM_SECTIONS +# pragma section(".CRT$XIA", read, long) /* start C initializers */ +# pragma section(".CRT$XIAA", read, long) +# pragma section(".CRT$XIZ", read, long) + +# pragma section(".CRT$XPA", read, long) /* start early C terminators */ +# pragma section(".CRT$XPAA", read, long) +# pragma section(".CRT$XPZ", read, long) + +# pragma section(".CRT$XTA", read, long) /* start C terminators */ +# pragma section(".CRT$XTAA", read, long) +# pragma section(".CRT$XTZ", read, long) +# define IPRT_COMPILER_TERM_CALLBACK(a_fn) \ + __declspec(allocate(".CRT$XTAA")) PFNRT RT_CONCAT(g_rtVccTermCallback_, a_fn) = a_fn +#endif + +#ifdef IPRT_COMPILER_VCC_WITH_CPP_INIT_SECTIONS +# pragma warning(disable:5247) /* warning C5247: section '.CRT$XCA' is reserved for C++ dynamic initialization. Manually creating the section will interfere with C++ dynamic initialization and may lead to undefined behavior */ +# pragma warning(disable:5248) /* warning C5248: section '.CRT$XCA' is reserved for C++ dynamic initialization. Variables manually put into the section may be optimized out and their order relative to compiler generated dynamic initializers is unspecified */ +# pragma section(".CRT$XCA", read, long) /* start C++ initializers */ +# pragma section(".CRT$XCAA", read, long) +# pragma section(".CRT$XCZ", read, long) +#endif + +#ifdef IPRT_COMPILER_VCC_WITH_RTC_INIT_TERM_SECTIONS +# pragma section(".rtc$IAA", read, long) /* start RTC initializers */ +# pragma section(".rtc$IZZ", read, long) + +# pragma section(".rtc$TAA", read, long) /* start RTC terminators */ +# pragma section(".rtc$TZZ", read, long) +#endif + +#ifdef IPRT_COMPILER_VCC_WITH_TLS_CALLBACK_SECTIONS +# pragma section(".CRT$XLA", read, long) /* start TLS callback */ +# pragma section(".CRT$XLAA", read, long) +# pragma section(".CRT$XLZ", read, long) + +/** @todo what about .CRT$XDA? Dynamic TLS initializers. */ +#endif + +#ifdef IPRT_COMPILER_VCC_WITH_TLS_DATA_SECTIONS +# pragma section(".tls", read, long) /* start TLS callback */ +# pragma section(".tls$ZZZ", read, long) + +/** @todo what about .CRT$XDA? Dynamic TLS initializers. */ +#endif + +/** @} */ + + +RT_C_DECLS_BEGIN + +extern unsigned _fltused; + +void rtVccInitSecurityCookie(void) RT_NOEXCEPT; +void rtVccWinInitBssOnNt3(void *pvImageBase) RT_NOEXCEPT; +void rtVccWinInitProcExecPath(void) RT_NOEXCEPT; +int rtVccInitializersRunInit(void) RT_NOEXCEPT; +void rtVccInitializersRunTerm(void) RT_NOEXCEPT; +void rtVccTermRunAtExit(void) RT_NOEXCEPT; + +struct _CONTEXT; +void rtVccCheckContextFailed(struct _CONTEXT *pCpuCtx); + +#ifdef _CONTROL_FLOW_GUARD +DECLASM(void) __guard_check_icall_nop(uintptr_t); /**< nocrt-guard-win.asm */ +#endif +extern uintptr_t __guard_check_icall_fptr; /**< nocrt-guard-win.asm */ + +RT_C_DECLS_END + + +/** + * Checks if CFG is currently active. + * + * This requires CFG to be enabled at compile time, supported by the host OS + * version and activated by the module loader. + * + * @returns true if CFG is active, false if not. + */ +DECLINLINE(bool) rtVccIsGuardICallChecksActive(void) +{ +#ifdef _CONTROL_FLOW_GUARD + return __guard_check_icall_fptr != (uintptr_t)__guard_check_icall_nop; +#else + return false; +#endif +} + + +#ifdef IPRT_INCLUDED_nt_nt_h +/** + * Checks if a pointer is on the officially registered stack or not. + * + * @returns true if on the official stack, false if not. + * @param uStackPtr The pointer to check. + */ +DECLINLINE(bool) rtVccIsPointerOnTheStack(uintptr_t uStackPtr) +{ + PNT_TIB const pTib = (PNT_TIB)RTNtCurrentTeb(); + return uStackPtr <= (uintptr_t)pTib->StackBase + && uStackPtr >= (uintptr_t)pTib->StackLimit; +} +#endif + +#endif /* !IPRT_INCLUDED_INTERNAL_compiler_vcc_h */ + diff --git a/src/VBox/Runtime/include/internal/dbgmod.h b/src/VBox/Runtime/include/internal/dbgmod.h new file mode 100644 index 00000000..c1a5c56e --- /dev/null +++ b/src/VBox/Runtime/include/internal/dbgmod.h @@ -0,0 +1,739 @@ +/* $Id: dbgmod.h $ */ +/** @file + * IPRT - Internal Header for RTDbgMod and the associated interpreters. + */ + +/* + * Copyright (C) 2008-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_INTERNAL_dbgmod_h +#define IPRT_INCLUDED_INTERNAL_dbgmod_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/types.h> +#include <iprt/critsect.h> +#include <iprt/ldr.h> /* for PFNRTLDRENUMDBG */ +#include "internal/magics.h" + +RT_C_DECLS_BEGIN + +/** @addtogroup grp_rt_dbgmod + * @internal + * @{ + */ + + +/** Pointer to the internal module structure. */ +typedef struct RTDBGMODINT *PRTDBGMODINT; + +/** + * Virtual method table for executable image interpreters. + */ +typedef struct RTDBGMODVTIMG +{ + /** Magic number (RTDBGMODVTIMG_MAGIC). */ + uint32_t u32Magic; + /** Reserved. */ + uint32_t fReserved; + /** The name of the interpreter. */ + const char *pszName; + + /** + * Try open the image. + * + * This combines probing and opening. + * + * @returns IPRT status code. No informational returns defined. + * + * @param pMod Pointer to the module that is being opened. + * + * The RTDBGMOD::pszDbgFile member will point to + * the filename of any debug info we're aware of + * on input. Also, or alternatively, it is expected + * that the interpreter will look for debug info in + * the executable image file when present and that it + * may ask the image interpreter for this when it's + * around. + * + * Upon successful return the method is expected to + * initialize pImgOps and pvImgPriv. + * @param enmArch The desired architecture. + * @param fLdrFlags Extra loader flags (RTLDR_O_XXX). + */ + DECLCALLBACKMEMBER(int, pfnTryOpen,(PRTDBGMODINT pMod, RTLDRARCH enmArch, uint32_t fLdrFlags)); + + /** + * Close the interpreter, freeing all associated resources. + * + * The caller sets the pDbgOps and pvDbgPriv RTDBGMOD members + * to NULL upon return. + * + * @param pMod Pointer to the module structure. + */ + DECLCALLBACKMEMBER(int, pfnClose,(PRTDBGMODINT pMod)); + + /** + * Enumerate the debug info contained in the executable image. + * + * Identical to RTLdrEnumDbgInfo. + * + * @returns IPRT status code or whatever pfnCallback returns. + * + * @param pMod Pointer to the module structure. + * @param pfnCallback The callback function. Ignore the module + * handle argument! + * @param pvUser The user argument. + */ + DECLCALLBACKMEMBER(int, pfnEnumDbgInfo,(PRTDBGMODINT pMod, PFNRTLDRENUMDBG pfnCallback, void *pvUser)); + + /** + * Enumerate the segments in the executable image. + * + * Identical to RTLdrEnumSegments. + * + * @returns IPRT status code or whatever pfnCallback returns. + * + * @param pMod Pointer to the module structure. + * @param pfnCallback The callback function. Ignore the module + * handle argument! + * @param pvUser The user argument. + */ + DECLCALLBACKMEMBER(int, pfnEnumSegments,(PRTDBGMODINT pMod, PFNRTLDRENUMSEGS pfnCallback, void *pvUser)); + + /** + * Enumerates the symbols exported by the module. + * + * @returns iprt status code, which might have been returned by pfnCallback. + * @param pMod Pointer to the module structure. + * @param fFlags Flags indicating what to return and such. + * @param BaseAddress The image base addressto use when calculating the + * symbol values. + * @param pfnCallback The callback function which each symbol is to be fed + * to. + * @param pvUser User argument to pass to the enumerator. + */ + DECLCALLBACKMEMBER(int, pfnEnumSymbols,(PRTDBGMODINT pMod, uint32_t fFlags, RTLDRADDR BaseAddress, + PFNRTLDRENUMSYMS pfnCallback, void *pvUser)); + + /** + * Gets the size of the loaded image. + * + * Identical to RTLdrSize. + * + * @returns The size in bytes, RTUINTPTR_MAX on failure. + * + * @param pMod Pointer to the module structure. + */ + DECLCALLBACKMEMBER(RTUINTPTR, pfnImageSize,(PRTDBGMODINT pMod)); + + /** + * Converts a link address to a segment:offset address (RVA included). + * + * @returns IPRT status code. + * + * @param pMod Pointer to the module structure. + * @param LinkAddress The link address to convert. + * @param piSeg The segment index. + * @param poffSeg Where to return the segment offset. + */ + DECLCALLBACKMEMBER(int, pfnLinkAddressToSegOffset,(PRTDBGMODINT pMod, RTLDRADDR LinkAddress, + PRTDBGSEGIDX piSeg, PRTLDRADDR poffSeg)); + + /** + * Converts an image relative virtual address to a segment:offset. + * + * @returns IPRT status code. + * + * @param pMod Pointer to the loader module structure. + * @param Rva The RVA to convert. + * @param piSeg The segment index. + * @param poffSeg Where to return the segment offset. + */ + DECLCALLBACKMEMBER(int, pfnRvaToSegOffset,(PRTDBGMODINT pMod, RTLDRADDR Rva, uint32_t *piSeg, PRTLDRADDR poffSeg)); + + /** + * Creates a read-only mapping of a part of the image file. + * + * @returns IPRT status code and *ppvMap set on success. + * + * @param pMod Pointer to the module structure. + * @param iDbgInfo The debug info ordinal number if the request + * corresponds exactly to a debug info part from + * pfnEnumDbgInfo. Otherwise, pass UINT32_MAX. + * @param off The offset into the image file. + * @param cb The number of bytes to map. + * @param ppvMap Where to return the mapping address on success. + * + * @remarks Fixups will only be applied if @a iDbgInfo is specified. + */ + DECLCALLBACKMEMBER(int, pfnMapPart,(PRTDBGMODINT pMod, uint32_t iDbgInfo, RTFOFF off, size_t cb, void const **ppvMap)); + + /** + * Unmaps memory previously mapped by pfnMapPart. + * + * @returns IPRT status code, *ppvMap set to NULL on success. + * + * @param pMod Pointer to the module structure. + * @param cb The size of the mapping. + * @param ppvMap The mapping address on input, NULL on + * successful return. + */ + DECLCALLBACKMEMBER(int, pfnUnmapPart,(PRTDBGMODINT pMod, size_t cb, void const **ppvMap)); + + /** + * Reads data from the image file. + * + * @returns IPRT status code, *ppvMap set to NULL on success. + * + * @param pMod Pointer to the module structure. + * @param iDbgInfoHint The debug info ordinal number hint, pass UINT32_MAX + * if not know or sure. + * @param off The offset into the image file. + * @param pvBuf The buffer to read into. + * @param cb The number of bytes to read. + */ + DECLCALLBACKMEMBER(int, pfnReadAt,(PRTDBGMODINT pMod, uint32_t iDbgInfoHint, RTFOFF off, void *pvBuf, size_t cb)); + + /** + * Gets the image format. + * + * @returns Valid image format on success, RTLDRFMT_INVALID if not supported. + * @param pMod Pointer to the module structure. + */ + DECLCALLBACKMEMBER(RTLDRFMT, pfnGetFormat,(PRTDBGMODINT pMod)); + + /** + * Gets the image architecture. + * + * @returns Valid image architecutre on success, RTLDRARCH_WHATEVER if not + * supported. + * @param pMod Pointer to the module structure. + */ + DECLCALLBACKMEMBER(RTLDRARCH, pfnGetArch,(PRTDBGMODINT pMod)); + + /** + * Generic method for querying image properties. + * + * @returns IPRT status code. + * @param pMod Pointer to the module structure. + * @param enmProp The property to query. + * @param pvBuf Pointer to the return buffer. + * @param cbBuf The size of the return buffer. + * @param pcbRet How many bytes was actually returned. In the + * case of VERR_BUFFER_OVERFLOW this will contain + * the required buffer size. Optional. + * @sa RTLdrQueryPropEx + */ + DECLCALLBACKMEMBER(int, pfnQueryProp,(PRTDBGMODINT pMod, RTLDRPROP enmProp, void *pvBuf, size_t cbBuf, size_t *pcbRet)); + + /** + * Try use unwind information to unwind one frame. + * + * @returns IPRT status code. Last informational status from stack reader callback. + * @retval VERR_DBG_NO_UNWIND_INFO if the module contains no unwind information. + * @retval VERR_DBG_UNWIND_INFO_NOT_FOUND if no unwind information was found + * for the location given by iSeg:off. + * + * @param pMod Pointer to the module structure. + * @param iSeg The segment number of the program counter. + * @param off The offset into @a iSeg. Together with @a iSeg + * this corresponds to the RTDBGUNWINDSTATE::uPc + * value pointed to by @a pState. + * @param pState The unwind state to work. + * + * @sa RTLdrUnwindFrame, RTDbgModUnwindFrame + */ + DECLCALLBACKMEMBER(int, pfnUnwindFrame,(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, RTUINTPTR off, PRTDBGUNWINDSTATE pState)); + + /** For catching initialization errors (RTDBGMODVTIMG_MAGIC). */ + uint32_t u32EndMagic; +} RTDBGMODVTIMG; +/** Pointer to a const RTDBGMODVTIMG. */ +typedef RTDBGMODVTIMG const *PCRTDBGMODVTIMG; + + +/** + * Virtual method table for debug info interpreters. + */ +typedef struct RTDBGMODVTDBG +{ + /** Magic number (RTDBGMODVTDBG_MAGIC). */ + uint32_t u32Magic; + /** Mask of supported debug info types, see grp_rt_dbg_type. + * Used to speed up the search for a suitable interpreter. */ + uint32_t fSupports; + /** The name of the interpreter. */ + const char *pszName; + + /** + * Try open the image. + * + * This combines probing and opening. + * + * @returns IPRT status code. No informational returns defined. + * + * @param pMod Pointer to the module that is being opened. + * + * The RTDBGMOD::pszDbgFile member will point to + * the filename of any debug info we're aware of + * on input. Also, or alternatively, it is expected + * that the interpreter will look for debug info in + * the executable image file when present and that it + * may ask the image interpreter for this when it's + * around. + * + * Upon successful return the method is expected to + * initialize pDbgOps and pvDbgPriv. + * @param enmArch The desired architecture. + */ + DECLCALLBACKMEMBER(int, pfnTryOpen,(PRTDBGMODINT pMod, RTLDRARCH enmArch)); + + /** + * Close the interpreter, freeing all associated resources. + * + * The caller sets the pDbgOps and pvDbgPriv RTDBGMOD members + * to NULL upon return. + * + * @param pMod Pointer to the module structure. + */ + DECLCALLBACKMEMBER(int, pfnClose,(PRTDBGMODINT pMod)); + + + + /** + * Converts an image relative virtual address address to a segmented address. + * + * @returns Segment index on success, NIL_RTDBGSEGIDX on failure. + * @param pMod Pointer to the module structure. + * @param uRva The image relative address to convert. + * @param poffSeg Where to return the segment offset. Optional. + */ + DECLCALLBACKMEMBER(RTDBGSEGIDX, pfnRvaToSegOff,(PRTDBGMODINT pMod, RTUINTPTR uRva, PRTUINTPTR poffSeg)); + + /** + * Image size when mapped if segments are mapped adjacently. + * + * For ELF, PE, and Mach-O images this is (usually) a natural query, for LX and + * NE and such it's a bit odder and the answer may not make much sense for them. + * + * @returns Image mapped size. + * @param pMod Pointer to the module structure. + */ + DECLCALLBACKMEMBER(RTUINTPTR, pfnImageSize,(PRTDBGMODINT pMod)); + + + + /** + * Adds a segment to the module (optional). + * + * @returns IPRT status code. + * @retval VERR_NOT_SUPPORTED if the interpreter doesn't support this feature. + * @retval VERR_DBG_SEGMENT_INDEX_CONFLICT if the segment index exists already. + * + * @param pMod Pointer to the module structure. + * @param uRva The segment image relative address. + * @param cb The segment size. + * @param pszName The segment name. + * @param cchName The length of the segment name. + * @param fFlags Segment flags. + * @param piSeg The segment index or NIL_RTDBGSEGIDX on input. + * The assigned segment index on successful return. + * Optional. + */ + DECLCALLBACKMEMBER(int, pfnSegmentAdd,(PRTDBGMODINT pMod, RTUINTPTR uRva, RTUINTPTR cb, const char *pszName, size_t cchName, + uint32_t fFlags, PRTDBGSEGIDX piSeg)); + + /** + * Gets the segment count. + * + * @returns Number of segments. + * @retval NIL_RTDBGSEGIDX if unknown. + * + * @param pMod Pointer to the module structure. + */ + DECLCALLBACKMEMBER(RTDBGSEGIDX, pfnSegmentCount,(PRTDBGMODINT pMod)); + + /** + * Gets information about a segment. + * + * @returns IPRT status code. + * @retval VERR_DBG_INVALID_SEGMENT_INDEX if iSeg is too high. + * + * @param pMod Pointer to the module structure. + * @param iSeg The segment. + * @param pSegInfo Where to store the segment information. + */ + DECLCALLBACKMEMBER(int, pfnSegmentByIndex,(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, PRTDBGSEGMENT pSegInfo)); + + + + /** + * Adds a symbol to the module (optional). + * + * @returns IPRT code. + * @retval VERR_NOT_SUPPORTED if the interpreter doesn't support this feature. + * + * @param pMod Pointer to the module structure. + * @param pszSymbol The symbol name. + * @param cchSymbol The length for the symbol name. + * @param iSeg The segment number (0-based). RTDBGMOD_SEG_RVA can be used. + * @param off The offset into the segment. + * @param cb The area covered by the symbol. 0 is fine. + * @param fFlags Flags. + * @param piOrdinal Where to return the symbol ordinal on success. If the + * interpreter doesn't do ordinals, this will be set to + * UINT32_MAX. Optional + */ + DECLCALLBACKMEMBER(int, pfnSymbolAdd,(PRTDBGMODINT pMod, const char *pszSymbol, size_t cchSymbol, + uint32_t iSeg, RTUINTPTR off, RTUINTPTR cb, uint32_t fFlags, + uint32_t *piOrdinal)); + + /** + * Gets the number of symbols in the module. + * + * This is used for figuring out the max value to pass to pfnSymbolByIndex among + * other things. + * + * @returns The number of symbols, UINT32_MAX if not known/supported. + * + * @param pMod Pointer to the module structure. + */ + DECLCALLBACKMEMBER(uint32_t, pfnSymbolCount,(PRTDBGMODINT pMod)); + + /** + * Queries symbol information by ordinal number. + * + * @returns IPRT status code. + * @retval VINF_SUCCESS on success, no informational status code. + * @retval VERR_DBG_NO_SYMBOLS if there aren't any symbols. + * @retval VERR_NOT_SUPPORTED if lookup by ordinal is not supported. + * @retval VERR_SYMBOL_NOT_FOUND if there is no symbol at that index. + * + * @param pMod Pointer to the module structure. + * @param iOrdinal The symbol ordinal number. + * @param pSymInfo Where to store the symbol information. + */ + DECLCALLBACKMEMBER(int, pfnSymbolByOrdinal,(PRTDBGMODINT pMod, uint32_t iOrdinal, PRTDBGSYMBOL pSymInfo)); + + /** + * Queries symbol information by symbol name. + * + * @returns IPRT status code. + * @retval VINF_SUCCESS on success, no informational status code. + * @retval VERR_DBG_NO_SYMBOLS if there aren't any symbols. + * @retval VERR_SYMBOL_NOT_FOUND if no suitable symbol was found. + * + * @param pMod Pointer to the module structure. + * @param pszSymbol The symbol name. + * @param cchSymbol The length of the symbol name. + * @param pSymInfo Where to store the symbol information. + */ + DECLCALLBACKMEMBER(int, pfnSymbolByName,(PRTDBGMODINT pMod, const char *pszSymbol, size_t cchSymbol, PRTDBGSYMBOL pSymInfo)); + + /** + * Queries symbol information by address. + * + * The returned symbol is what the debug info interpreter considers the symbol + * most applicable to the specified address. This usually means a symbol with an + * address equal or lower than the requested. + * + * @returns IPRT status code. + * @retval VINF_SUCCESS on success, no informational status code. + * @retval VERR_DBG_NO_SYMBOLS if there aren't any symbols. + * @retval VERR_SYMBOL_NOT_FOUND if no suitable symbol was found. + * + * @param pMod Pointer to the module structure. + * @param iSeg The segment number (0-based) or RTDBGSEGIDX_ABS. + * @param off The offset into the segment. + * @param fFlags Symbol search flags, see RTDBGSYMADDR_FLAGS_XXX. + * @param poffDisp Where to store the distance between the specified address + * and the returned symbol. Optional. + * @param pSymInfo Where to store the symbol information. + */ + DECLCALLBACKMEMBER(int, pfnSymbolByAddr,(PRTDBGMODINT pMod, uint32_t iSeg, RTUINTPTR off, uint32_t fFlags, + PRTINTPTR poffDisp, PRTDBGSYMBOL pSymInfo)); + + + + /** + * Adds a line number to the module (optional). + * + * @returns IPRT status code. + * @retval VERR_NOT_SUPPORTED if the interpreter doesn't support this feature. + * + * @param pMod Pointer to the module structure. + * @param pszFile The filename. + * @param cchFile The length of the filename. + * @param uLineNo The line number. + * @param iSeg The segment number (0-based). + * @param off The offset into the segment. + * @param piOrdinal Where to return the line number ordinal on success. If + * the interpreter doesn't do ordinals, this will be set to + * UINT32_MAX. Optional + */ + DECLCALLBACKMEMBER(int, pfnLineAdd,(PRTDBGMODINT pMod, const char *pszFile, size_t cchFile, uint32_t uLineNo, + uint32_t iSeg, RTUINTPTR off, uint32_t *piOrdinal)); + + /** + * Gets the number of line numbers in the module. + * + * @returns The number or UINT32_MAX if not known/supported. + * + * @param pMod Pointer to the module structure. + */ + DECLCALLBACKMEMBER(uint32_t, pfnLineCount,(PRTDBGMODINT pMod)); + + /** + * Queries line number information by ordinal number. + * + * @returns IPRT status code. + * @retval VINF_SUCCESS on success, no informational status code. + * @retval VERR_DBG_NO_LINE_NUMBERS if there aren't any line numbers. + * @retval VERR_DBG_LINE_NOT_FOUND if there is no line number with that + * ordinal. + * + * @param pMod Pointer to the module structure. + * @param iOrdinal The line number ordinal number. + * @param pLineInfo Where to store the information about the line number. + */ + DECLCALLBACKMEMBER(int, pfnLineByOrdinal,(PRTDBGMODINT pMod, uint32_t iOrdinal, PRTDBGLINE pLineInfo)); + + /** + * Queries line number information by address. + * + * @returns IPRT status code. + * @retval VINF_SUCCESS on success, no informational status code. + * @retval VERR_DBG_NO_LINE_NUMBERS if there aren't any line numbers. + * @retval VERR_DBG_LINE_NOT_FOUND if no suitable line number was found. + * + * @param pMod Pointer to the module structure. + * @param iSeg The segment number (0-based) or RTDBGSEGIDX_ABS. + * @param off The offset into the segment. + * @param poffDisp Where to store the distance between the specified address + * and the returned line number. Optional. + * @param pLineInfo Where to store the information about the closest line + * number. + */ + DECLCALLBACKMEMBER(int, pfnLineByAddr,(PRTDBGMODINT pMod, uint32_t iSeg, RTUINTPTR off, + PRTINTPTR poffDisp, PRTDBGLINE pLineInfo)); + + /** + * Try use unwind information to unwind one frame. + * + * @returns IPRT status code. Last informational status from stack reader callback. + * @retval VERR_DBG_NO_UNWIND_INFO if the module contains no unwind information. + * @retval VERR_DBG_UNWIND_INFO_NOT_FOUND if no unwind information was found + * for the location given by iSeg:off. + * + * @param pMod Pointer to the module structure. + * @param iSeg The segment number of the program counter. + * @param off The offset into @a iSeg. Together with @a iSeg + * this corresponds to the RTDBGUNWINDSTATE::uPc + * value pointed to by @a pState. + * @param pState The unwind state to work. + * + * @sa RTDbgModUnwindFrame + */ + DECLCALLBACKMEMBER(int, pfnUnwindFrame,(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, RTUINTPTR off, PRTDBGUNWINDSTATE pState)); + + /** For catching initialization errors (RTDBGMODVTDBG_MAGIC). */ + uint32_t u32EndMagic; +} RTDBGMODVTDBG; +/** Pointer to a const RTDBGMODVTDBG. */ +typedef RTDBGMODVTDBG const *PCRTDBGMODVTDBG; + + +/** + * Deferred loading callback. + * + * @returns IPRT status code. On success the necessary method tables should be + * installed in @a pMod. + * @param pDbgMod Pointer to the debug module structure. + * @param pDeferred The deferred load data. + */ +typedef DECLCALLBACKTYPE(int, FNRTDBGMODDEFERRED,(PRTDBGMODINT pDbgMod, struct RTDBGMODDEFERRED *pDeferred)); +/** Pointer to a deferred loading callback. */ +typedef FNRTDBGMODDEFERRED *PFNRTDBGMODDEFERRED; + + +/** + * Structure pointed to by pvDbgPriv and/or pvImgPriv when + * g_rtDbgModVtDbgDeferred and/or g_rtDbgModVtImgDeferred are being used. + */ +typedef struct RTDBGMODDEFERRED +{ + /** Magic value (RTDBGMODDEFERRED_MAGIC). */ + uint32_t u32Magic; + /** Reference counter. */ + uint32_t volatile cRefs; + /** RTDBGMOD_F_XXX */ + uint32_t fFlags; + /** The image size. + * Deferred loading is almost pointless without knowing the module size, as + * it cannot be mapped (correctly) without it. */ + RTUINTPTR cbImage; + /** The configuration instance (referenced), can be NIL. */ + RTDBGCFG hDbgCfg; + /** Performs deferred loading of the module. */ + PFNRTDBGMODDEFERRED pfnDeferred; + /** Callback specific data. */ + union + { + struct + { + /** The time/date stamp of the executable image and codeview file. */ + uint32_t uTimestamp; + } PeImage, + OldCodeView; + + struct + { + /** The PDB uuid. */ + RTUUID Uuid; + /** The PDB age. */ + uint32_t uAge; + } NewCodeview; + + struct + { + /** The CRC-32 value found in the .gnu_debuglink section. */ + uint32_t uCrc32; + } GnuDebugLink; + + struct + { + /** The image UUID. */ + RTUUID Uuid; + /** Image architecture. */ + RTLDRARCH enmArch; + /** Number of segment mappings. */ + uint32_t cSegs; + /** Segment mappings. */ + RTDBGSEGMENT aSegs[1]; + } MachO; + } u; +} RTDBGMODDEFERRED; +/** Pointer to the deferred loading data. */ +typedef RTDBGMODDEFERRED *PRTDBGMODDEFERRED; + + +/** + * Debug module structure. + */ +typedef struct RTDBGMODINT +{ + /** Magic value (RTDBGMOD_MAGIC). */ + uint32_t u32Magic; + /** The number of reference there are to this module. + * This is used to perform automatic cleanup and sharing. */ + uint32_t volatile cRefs; + /** The module tag. */ + uint64_t uTag; + + /** When set, the loading of the image and debug info (including locating any + * external files), will not have taken place yet. */ + uint32_t fDeferred : 1; + /** Set if deferred loading failed. */ + uint32_t fDeferredFailed : 1; + /** Set if the debug info is based on image exports and segments. */ + uint32_t fExports : 1; + /** Alignment padding. */ + uint32_t fPadding1 : 29; +#if ARCH_BITS == 64 + uint32_t u32Padding2; +#endif + + /** The module name (short). */ + char const *pszName; + /** The image file specified by the user. Can be NULL. */ + char const *pszImgFileSpecified; + /** The module filename. Can be NULL. */ + char const *pszImgFile; + /** The debug info file (if external). Can be NULL. */ + char const *pszDbgFile; + + /** The method table for the executable image interpreter. */ + PCRTDBGMODVTIMG pImgVt; + /** Pointer to the private data of the executable image interpreter. */ + void *pvImgPriv; + + /** The method table for the debug info interpreter. */ + PCRTDBGMODVTDBG pDbgVt; + /** Pointer to the private data of the debug info interpreter. */ + void *pvDbgPriv; + + /** Critical section serializing access to the module. */ + RTCRITSECT CritSect; +} RTDBGMODINT; +/** Pointer to an debug module structure. */ +typedef RTDBGMODINT *PRTDBGMODINT; + + +extern DECL_HIDDEN_DATA(RTSTRCACHE) g_hDbgModStrCache; +extern DECL_HIDDEN_DATA(RTDBGMODVTDBG const) g_rtDbgModVtDbgCodeView; +extern DECL_HIDDEN_DATA(RTDBGMODVTDBG const) g_rtDbgModVtDbgDwarf; +extern DECL_HIDDEN_DATA(RTDBGMODVTDBG const) g_rtDbgModVtDbgNm; +extern DECL_HIDDEN_DATA(RTDBGMODVTDBG const) g_rtDbgModVtDbgMapSym; +#ifdef IPRT_WITH_GHIDRA_DBG_MOD +extern DECL_HIDDEN_DATA(RTDBGMODVTDBG const) g_rtDbgModVtDbgGhidra; +#endif +#ifdef RT_OS_WINDOWS +extern DECL_HIDDEN_DATA(RTDBGMODVTDBG const) g_rtDbgModVtDbgDbgHelp; +#endif +extern DECL_HIDDEN_DATA(RTDBGMODVTDBG const) g_rtDbgModVtDbgDeferred; +extern DECL_HIDDEN_DATA(RTDBGMODVTDBG const) g_rtDbgModVtDbgContainer; + +extern DECL_HIDDEN_DATA(RTDBGMODVTIMG const) g_rtDbgModVtImgLdr; +extern DECL_HIDDEN_DATA(RTDBGMODVTIMG const) g_rtDbgModVtImgDeferred; + +DECLHIDDEN(int) rtDbgModContainerCreate(PRTDBGMODINT pMod, RTUINTPTR cbSeg); +DECLHIDDEN(int) rtDbgModContainer_SymbolRemoveAll(PRTDBGMODINT pMod); +DECLHIDDEN(int) rtDbgModContainer_LineRemoveAll(PRTDBGMODINT pMod); +DECLHIDDEN(int) rtDbgModContainer_RemoveAll(PRTDBGMODINT pMod); + +DECLHIDDEN(int) rtDbgModCreateForExports(PRTDBGMODINT pDbgMod); +DECLHIDDEN(int) rtDbgModDeferredCreate(PRTDBGMODINT pDbgMod, PFNRTDBGMODDEFERRED pfnDeferred, RTUINTPTR cbImage, + RTDBGCFG hDbgCfg, size_t cbDeferred, uint32_t fFlags, PRTDBGMODDEFERRED *ppDeferred); + +DECLHIDDEN(int) rtDbgModLdrOpenFromHandle(PRTDBGMODINT pDbgMod, RTLDRMOD hLdrMod); + +DECLHIDDEN(int) rtDwarfUnwind_EhData(void const *pvSection, size_t cbSection, RTUINTPTR uRvaSection, + RTDBGSEGIDX idxSeg, RTUINTPTR offSeg, RTUINTPTR uRva, + PRTDBGUNWINDSTATE pState, RTLDRARCH enmArch); + +/** @} */ + +RT_C_DECLS_END + +#endif /* !IPRT_INCLUDED_INTERNAL_dbgmod_h */ + diff --git a/src/VBox/Runtime/include/internal/dir.h b/src/VBox/Runtime/include/internal/dir.h new file mode 100644 index 00000000..a9006ed6 --- /dev/null +++ b/src/VBox/Runtime/include/internal/dir.h @@ -0,0 +1,206 @@ +/* $Id: dir.h $ */ +/** @file + * IPRT - Internal Header for RTDir. + */ + +/* + * Copyright (C) 2006-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_INTERNAL_dir_h +#define IPRT_INCLUDED_INTERNAL_dir_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/cdefs.h> +#include <iprt/types.h> +#include "internal/magics.h" + + +/** Pointer to the data behind an open directory handle. */ +typedef struct RTDIRINTERNAL *PRTDIRINTERNAL; + +/** + * Filter a the filename in the against a filter. + * + * @returns true if the name matches the filter. + * @returns false if the name doesn't match filter. + * @param pDir The directory handle. + * @param pszName The path to match to the filter. + */ +typedef DECLCALLBACKTYPE(bool, FNRTDIRFILTER,(PRTDIRINTERNAL pDir, const char *pszName)); +/** Pointer to a filter function. */ +typedef FNRTDIRFILTER *PFNRTDIRFILTER; + + +/** + * Open directory. + */ +typedef struct RTDIRINTERNAL +{ + /** Magic value, RTDIR_MAGIC. */ + uint32_t u32Magic; + /** The type of filter that's to be applied to the directory listing. */ + RTDIRFILTER enmFilter; + /** The filter function. */ + PFNRTDIRFILTER pfnFilter; + /** The filter Code Point string. + * This is allocated in the same block as this structure. */ + PRTUNICP puszFilter; + /** The number of Code Points in the filter string. */ + size_t cucFilter; + /** The filter string. + * This is allocated in the same block as this structure, thus the const. */ + const char *pszFilter; + /** The length of the filter string. */ + size_t cchFilter; + /** Normalized path to the directory including a trailing slash. + * We keep this around so we can query more information if required (posix). + * This is allocated in the same block as this structure, thus the const. */ + const char *pszPath; + /** The length of the path. */ + size_t cchPath; + /** Pointer to the converted filename. + * This can be NULL. */ +#ifdef RT_OS_WINDOWS + char *pszName; +#else + char const *pszName; +#endif + /** The length of the converted filename. */ + size_t cchName; + /** The size of this structure. */ + size_t cbSelf; + /** The RTDIR_F_XXX flags passed to RTDirOpenFiltered */ + uint32_t fFlags; + /** Set if the specified path included a directory slash or if enmFilter is not RTDIRFILTER_NONE. + * This is relevant for how to interpret the RTDIR_F_NO_FOLLOW flag, as it won't + * have any effect if the specified path ends with a slash on posix systems. We + * implement that on the other systems too, for consistency. */ + bool fDirSlash; + /** Set to indicate that the Data member contains unread data. */ + bool fDataUnread; + +#ifndef RTDIR_AGNOSTIC +# ifdef RT_OS_WINDOWS + /** Set by RTDirRewind. */ + bool fRestartScan; + /** Handle to the opened directory search. */ + HANDLE hDir; +# ifndef RTNT_USE_NATIVE_NT + /** Find data buffer. + * fDataUnread indicates valid data. */ + WIN32_FIND_DATAW Data; +# else + /** The size of the name buffer pszName points to. */ + size_t cbNameAlloc; + /** NT filter string. */ + UNICODE_STRING NtFilterStr; + /** Pointer to NtFilterStr if applicable, otherwise NULL. */ + PUNICODE_STRING pNtFilterStr; + /** The information class we're using. */ + FILE_INFORMATION_CLASS enmInfoClass; + /** Object directory context data. */ + ULONG uObjDirCtx; + /** Pointer to the current data entry in the buffer. */ + union + { + /** Both file names, no file ID. */ + PFILE_BOTH_DIR_INFORMATION pBoth; + /** Both file names with file ID. */ + PFILE_ID_BOTH_DIR_INFORMATION pBothId; + /** Object directory info. */ + POBJECT_DIRECTORY_INFORMATION pObjDir; + /** Unsigned view. */ + uintptr_t u; + } uCurData; + /** The amount of valid data in the buffer. */ + uint32_t cbBuffer; + /** The allocate buffer size. */ + uint32_t cbBufferAlloc; + /** Find data buffer containing multiple directory entries. + * fDataUnread indicates valid data. */ + uint8_t *pabBuffer; + /** The device number for the directory (serial number). */ + RTDEV uDirDev; +# endif +# else /* 'POSIX': */ + /** What opendir() returned. */ + DIR *pDir; + /** Find data buffer. + * fDataUnread indicates valid data. */ + struct dirent Data; +# endif +#endif +} RTDIRINTERNAL; + + + +/** + * Validates a directory handle. + * @returns true if valid. + * @returns false if valid after having bitched about it first. + */ +DECLINLINE(bool) rtDirValidHandle(PRTDIRINTERNAL pDir) +{ + AssertPtrReturn(pDir, false); + AssertMsgReturn(pDir->u32Magic == RTDIR_MAGIC, ("%#RX32\n", pDir->u32Magic), false); + return true; +} + + +/** + * Initialize the OS specific part of the handle and open the directory. + * Called by rtDirOpenCommon(). + * + * @returns IPRT status code. + * @param pDir The directory to open. The pszPath member contains the + * path to the directory. + * @param hRelativeDir The directory @a pvNativeRelative is relative, + * ~(uintptr_t)0 if absolute. + * @param pvNativeRelative The native relative path. NULL if absolute or + * we're to use (consume) hRelativeDir. + */ +int rtDirNativeOpen(PRTDIRINTERNAL pDir, uintptr_t hRelativeDir, void *pvNativeRelative); + +/** + * Returns the size of the directory structure. + * + * @returns The size in bytes. + * @param pszPath The path to the directory we're about to open. + */ +size_t rtDirNativeGetStructSize(const char *pszPath); + + +DECLHIDDEN(int) rtDirOpenRelativeOrHandle(RTDIR *phDir, const char *pszRelativeAndFilter, RTDIRFILTER enmFilter, + uint32_t fFlags, uintptr_t hRelativeDir, void *pvNativeRelative); + +#endif /* !IPRT_INCLUDED_INTERNAL_dir_h */ diff --git a/src/VBox/Runtime/include/internal/dvm.h b/src/VBox/Runtime/include/internal/dvm.h new file mode 100644 index 00000000..af212e74 --- /dev/null +++ b/src/VBox/Runtime/include/internal/dvm.h @@ -0,0 +1,450 @@ +/* $Id: dvm.h $ */ +/** @file + * IPRT - Disk Volume Management Internals. + */ + +/* + * Copyright (C) 2006-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_INTERNAL_dvm_h +#define IPRT_INCLUDED_INTERNAL_dvm_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/types.h> +#include <iprt/err.h> +#include <iprt/assert.h> +#include <iprt/vfs.h> +#include "internal/magics.h" + +RT_C_DECLS_BEGIN + +/** Format specific volume manager handle. */ +typedef struct RTDVMFMTINTERNAL *RTDVMFMT; +/** Pointer to a format specific volume manager handle. */ +typedef RTDVMFMT *PRTDVMFMT; +/** NIL volume manager handle. */ +#define NIL_RTDVMFMT ((RTDVMFMT)~0) + +/** Format specific volume data handle. */ +typedef struct RTDVMVOLUMEFMTINTERNAL *RTDVMVOLUMEFMT; +/** Pointer to a format specific volume data handle. */ +typedef RTDVMVOLUMEFMT *PRTDVMVOLUMEFMT; +/** NIL volume handle. */ +#define NIL_RTDVMVOLUMEFMT ((RTDVMVOLUMEFMT)~0) + +/** + * Disk descriptor. + */ +typedef struct RTDVMDISK +{ + /** Size of the disk in bytes. */ + uint64_t cbDisk; + /** Sector size. */ + uint64_t cbSector; + /** The VFS file handle if backed by such. */ + RTVFSFILE hVfsFile; +} RTDVMDISK; +/** Pointer to a disk descriptor. */ +typedef RTDVMDISK *PRTDVMDISK; +/** Pointer to a const descriptor. */ +typedef const RTDVMDISK *PCRTDVMDISK; + +/** Score to indicate that the backend can't handle the format at all */ +#define RTDVM_MATCH_SCORE_UNSUPPORTED 0 +/** Score to indicate that a backend supports the format + * but there can be other backends. */ +#define RTDVM_MATCH_SCORE_SUPPORTED (UINT32_MAX/2) +/** Score to indicate a perfect match. */ +#define RTDVM_MATCH_SCORE_PERFECT UINT32_MAX + +/** + * Volume format operations. + */ +typedef struct RTDVMFMTOPS +{ + /** Name of the format. */ + const char *pszFmt; + /** The format type. */ + RTDVMFORMATTYPE enmFormat; + + /** + * Probes the given disk for known structures. + * + * @returns IPRT status code. + * @param pDisk Disk descriptor. + * @param puScore Where to store the match score on success. + */ + DECLCALLBACKMEMBER(int, pfnProbe,(PCRTDVMDISK pDisk, uint32_t *puScore)); + + /** + * Opens the format to set up all structures. + * + * @returns IPRT status code. + * @param pDisk The disk descriptor. + * @param phVolMgrFmt Where to store the volume format data on success. + */ + DECLCALLBACKMEMBER(int, pfnOpen,(PCRTDVMDISK pDisk, PRTDVMFMT phVolMgrFmt)); + + /** + * Initializes a new volume map. + * + * @returns IPRT status code. + * @param pDisk The disk descriptor. + * @param phVolMgrFmt Where to store the volume format data on success. + */ + DECLCALLBACKMEMBER(int, pfnInitialize,(PCRTDVMDISK pDisk, PRTDVMFMT phVolMgrFmt)); + + /** + * Closes the volume format. + * + * @param hVolMgrFmt The format specific volume manager handle. + */ + DECLCALLBACKMEMBER(void, pfnClose,(RTDVMFMT hVolMgrFmt)); + + /** + * Returns whether the given range is in use by the volume manager. + * + * @returns IPRT status code. + * @param hVolMgrFmt The format specific volume manager handle. + * @param offStart Start offset of the range. + * @param cbRange Size of the range to check in bytes. + * @param pfUsed Where to store whether the range is in use by the + * volume manager. + */ + DECLCALLBACKMEMBER(int, pfnQueryRangeUse,(RTDVMFMT hVolMgrFmt, + uint64_t off, uint64_t cbRange, + bool *pfUsed)); + + /** + * Optional: Query the uuid of the current disk if applicable. + * + * @returns IPRT status code. + * @retval VERR_NOT_SUPPORTED if the partition scheme doesn't do UUIDs. + * @param hVolMgrFmt The format specific volume manager handle. + * @param pUuid Where to return the UUID. + */ + DECLCALLBACKMEMBER(int, pfnQueryDiskUuid,(RTDVMFMT hVolMgrFmt, PRTUUID pUuid)); + + /** + * Gets the number of valid volumes in the map. + * + * @returns Number of valid volumes in the map or UINT32_MAX on failure. + * @param hVolMgrFmt The format specific volume manager handle. + */ + DECLCALLBACKMEMBER(uint32_t, pfnGetValidVolumes,(RTDVMFMT hVolMgrFmt)); + + /** + * Gets the maximum number of volumes the map can have. + * + * @returns Maximum number of volumes in the map or 0 on failure. + * @param hVolMgrFmt The format specific volume manager handle. + */ + DECLCALLBACKMEMBER(uint32_t, pfnGetMaxVolumes,(RTDVMFMT hVolMgrFmt)); + + /** + * Get the first valid volume from a map. + * + * @returns IPRT status code. + * @param hVolMgrFmt The format specific volume manager handle. + * @param phVolFmt Where to store the volume handle to the first volume + * on success. + */ + DECLCALLBACKMEMBER(int, pfnQueryFirstVolume,(RTDVMFMT hVolMgrFmt, PRTDVMVOLUMEFMT phVolFmt)); + + /** + * Get the first valid volume from a map. + * + * @returns IPRT status code. + * @param hVolMgrFmt The format specific volume manager handle. + * @param hVolFmt The current volume. + * @param phVolFmtNext Where to store the handle to the format specific + * volume data of the next volume on success. + */ + DECLCALLBACKMEMBER(int, pfnQueryNextVolume,(RTDVMFMT hVolMgrFmt, RTDVMVOLUMEFMT hVolFmt, PRTDVMVOLUMEFMT phVolFmtNext)); + + /** + * Query the partition table locations. + * + * @returns IPRT status code. + * @retval VERR_BUFFER_OVERFLOW if the table is too small, @a *pcActual will be + * set to the required size. + * @retval VERR_BUFFER_UNDERFLOW if the table is too big and @a pcActual is + * NULL. + * @param hVolMgrFmt The format specific volume manager handle. + * @param fFlags Flags, see RTDVMMAPQTABLOC_F_XXX. + * @param paLocations Where to return the info. Ignored if @a cLocations + * is zero, then only @a pcActual matters. + * @param cLocations The size of @a paLocations in items. + * @param pcActual Where to return the actual number of locations, or + * on VERR_BUFFER_OVERFLOW the necessary table size. + * Optional, when not specified the cLocations value + * must match exactly or it fails with + * VERR_BUFFER_UNDERFLOW. + * @sa RTDvmMapQueryTableLocations + */ + DECLCALLBACKMEMBER(int, pfnQueryTableLocations,(RTDVMFMT hVolMgrFmt, uint32_t fFlags, PRTDVMTABLELOCATION paLocations, + size_t cLocations, size_t *pcActual)); + + /** + * Closes a volume handle. + * + * @param hVolFmt The format specific volume handle. + */ + DECLCALLBACKMEMBER(void, pfnVolumeClose,(RTDVMVOLUMEFMT hVolFmt)); + + /** + * Gets the size of the given volume. + * + * @returns Size of the volume in bytes or 0 on failure. + * @param hVolFmt The format specific volume handle. + */ + DECLCALLBACKMEMBER(uint64_t, pfnVolumeGetSize,(RTDVMVOLUMEFMT hVolFmt)); + + /** + * Queries the name of the given volume. + * + * @returns IPRT status code. + * @param hVolFmt The format specific volume handle. + * @param ppszVolname Where to store the name of the volume on success. + */ + DECLCALLBACKMEMBER(int, pfnVolumeQueryName,(RTDVMVOLUMEFMT hVolFmt, char **ppszVolName)); + + /** + * Get the type of the given volume. + * + * @returns The volume type on success, DVMVOLTYPE_INVALID if hVol is invalid. + * @param hVolFmt The format specific volume handle. + */ + DECLCALLBACKMEMBER(RTDVMVOLTYPE, pfnVolumeGetType,(RTDVMVOLUMEFMT hVolFmt)); + + /** + * Get the flags of the given volume. + * + * @returns The volume flags or UINT64_MAX on failure. + * @param hVolFmt The format specific volume handle. + */ + DECLCALLBACKMEMBER(uint64_t, pfnVolumeGetFlags,(RTDVMVOLUMEFMT hVolFmt)); + + /** + * Queries the range of the given volume on the underyling medium. + * + * @returns IPRT status code. + * @param hVolFmt The format specific volume handle. + * @param poffStart Where to store the start byte offset on the + * underlying medium. + * @param poffLast Where to store the last byte offset on the + * underlying medium (inclusive). + */ + DECLCALLBACKMEMBER(int, pfnVolumeQueryRange,(RTDVMVOLUMEFMT hVolFmt, uint64_t *poffStart, uint64_t *poffLast)); + + /** + * Returns whether the supplied range is at least partially intersecting + * with the given volume. + * + * @returns whether the range intersects with the volume. + * @param hVolFmt The format specific volume handle. + * @param offStart Start offset of the range. + * @param cbRange Size of the range to check in bytes. + * @param poffVol Where to store the offset of the range from the + * start of the volume if true is returned. + * @param pcbIntersect Where to store the number of bytes intersecting + * with the range if true is returned. + */ + DECLCALLBACKMEMBER(bool, pfnVolumeIsRangeIntersecting,(RTDVMVOLUMEFMT hVolFmt, + uint64_t offStart, size_t cbRange, + uint64_t *poffVol, + uint64_t *pcbIntersect)); + + /** + * Queries the range of the partition table the volume belongs to on the underlying medium. + * + * @returns IPRT status code. + * @param hVolFmt The format specific volume handle. + * @param poffTable Where to return the byte offset on the underlying + * media of the (partition/volume/whatever) table. + * @param pcbTable Where to return the table size in bytes. This + * typically includes alignment padding. + * @sa RTDvmVolumeQueryTableLocation + */ + DECLCALLBACKMEMBER(int, pfnVolumeQueryTableLocation,(RTDVMVOLUMEFMT hVolFmt, uint64_t *poffStart, uint64_t *poffLast)); + + /** + * Gets the tiven index for the specified volume. + * + * @returns The requested index. UINT32_MAX on failure. + * @param hVolFmt The format specific volume handle. + * @param enmIndex The index to get. Never RTDVMVOLIDX_HOST. + * @sa RTDvmVolumeGetIndex + */ + DECLCALLBACKMEMBER(uint32_t, pfnVolumeGetIndex,(RTDVMVOLUMEFMT hVolFmt, RTDVMVOLIDX enmIndex)); + + /** + * Query a generic volume property. + * + * This is an extensible interface for retriving mostly format specific + * information, or information that's not commonly used. (It's modelled after + * RTLdrQueryPropEx.) + * + * @returns IPRT status code. + * @retval VERR_NOT_SUPPORTED if the property query isn't supported (either all + * or that specific property). The caller must handle this result. + * @retval VERR_NOT_FOUND is currently not returned, but intended for cases + * where it wasn't present in the tables. + * @retval VERR_INVALID_FUNCTION if the @a enmProperty value is wrong. + * @retval VERR_INVALID_PARAMETER if the fixed buffer size is wrong. Correct + * size in @a *pcbBuf. + * @retval VERR_BUFFER_OVERFLOW if the property doesn't have a fixed size + * buffer and the buffer isn't big enough. Correct size in @a *pcbBuf. + * @retval VERR_INVALID_HANDLE if the handle is invalid. + * + * @param hVolFmt Handle to the volume. + * @param enmProperty The property to query. + * @param pvBuf Pointer to the input / output buffer. In most cases + * it's only used for returning data. + * @param cbBuf The size of the buffer. This is validated by the common + * code for all fixed typed & sized properties. The + * interger properties may have several supported sizes, in + * which case the user value is passed along as-is but it + * is okay to return a smaller amount of data. The common + * code will make upcast the data. + * @param pcbBuf Where to return the amount of data returned. This must + * be set even for fixed type/sized data. + * @sa RTDvmVolumeQueryProp, RTDvmVolumeGetPropU64 + */ + DECLCALLBACKMEMBER(int, pfnVolumeQueryProp,(RTDVMVOLUMEFMT hVolFmt, RTDVMVOLPROP enmProperty, + void *pvBuf, size_t cbBuf, size_t *pcbBuf)); + + /** + * Read data from the given volume. + * + * @returns IPRT status code. + * @param hVolFmt The format specific volume handle. + * @param off Where to start reading from. + * @param pvBuf Where to store the read data. + * @param cbRead How many bytes to read. + */ + DECLCALLBACKMEMBER(int, pfnVolumeRead,(RTDVMVOLUMEFMT hVolFmt, uint64_t off, void *pvBuf, size_t cbRead)); + + /** + * Write data to the given volume. + * + * @returns IPRT status code. + * @param hVolFmt The format specific volume handle. + * @param off Where to start writing to. + * @param pvBuf The data to write. + * @param cbWrite How many bytes to write. + */ + DECLCALLBACKMEMBER(int, pfnVolumeWrite,(RTDVMVOLUMEFMT hVolFmt, uint64_t off, const void *pvBuf, size_t cbWrite)); + +} RTDVMFMTOPS; +/** Pointer to a DVM ops table. */ +typedef RTDVMFMTOPS *PRTDVMFMTOPS; +/** Pointer to a const DVM ops table. */ +typedef const RTDVMFMTOPS *PCRTDVMFMTOPS; + +/** Checks whether a range is intersecting. */ +#define RTDVM_RANGE_IS_INTERSECTING(start, size, off) ( (start) <= (off) && ((start) + (size)) > (off) ) + +/** Converts a LBA number to the byte offset. */ +#define RTDVM_LBA2BYTE(lba, disk) ((lba) * (disk)->cbSector) +/** Converts a Byte offset to the LBA number. */ +#define RTDVM_BYTE2LBA(off, disk) ((off) / (disk)->cbSector) + +/** + * Returns the number of sectors in the disk. + * + * @returns Number of sectors. + * @param pDisk The disk descriptor. + */ +DECLINLINE(uint64_t) rtDvmDiskGetSectors(PCRTDVMDISK pDisk) +{ + return pDisk->cbDisk / pDisk->cbSector; +} + +/** + * Read from the disk at the given offset. + * + * @returns IPRT status code. + * @param pDisk The disk descriptor to read from. + * @param off Start offset. + * @param pvBuf Destination buffer. + * @param cbRead How much to read. + * @sa rtDvmDiskReadUnaligned + */ +DECLINLINE(int) rtDvmDiskRead(PCRTDVMDISK pDisk, uint64_t off, void *pvBuf, size_t cbRead) +{ + AssertPtrReturn(pDisk, VERR_INVALID_POINTER); + AssertPtrReturn(pvBuf, VERR_INVALID_POINTER); + AssertReturn(cbRead > 0, VERR_INVALID_PARAMETER); + AssertReturn(off + cbRead <= pDisk->cbDisk, VERR_INVALID_PARAMETER); + + /* Use RTVfsFileReadAt if these triggers: */ + Assert(!(cbRead % pDisk->cbSector)); + Assert(!(off % pDisk->cbSector)); + + return RTVfsFileReadAt(pDisk->hVfsFile, off, pvBuf, cbRead, NULL /*pcbRead*/); +} + +DECLHIDDEN(int) rtDvmDiskReadUnaligned(PCRTDVMDISK pDisk, uint64_t off, void *pvBuf, size_t cbRead); + +/** + * Write to the disk at the given offset. + * + * @returns IPRT status code. + * @param pDisk The disk descriptor to write to. + * @param off Start offset. + * @param pvBuf Source buffer. + * @param cbWrite How much to write. + */ +DECLINLINE(int) rtDvmDiskWrite(PCRTDVMDISK pDisk, uint64_t off, const void *pvBuf, size_t cbWrite) +{ + AssertPtrReturn(pDisk, VERR_INVALID_POINTER); + AssertPtrReturn(pvBuf, VERR_INVALID_POINTER); + AssertReturn(cbWrite > 0, VERR_INVALID_PARAMETER); + AssertReturn(off + cbWrite <= pDisk->cbDisk, VERR_INVALID_PARAMETER); + + /* Write RTVfsFileReadAt if these triggers: */ + Assert(!(cbWrite % pDisk->cbSector)); + Assert(!(off % pDisk->cbSector)); + + return RTVfsFileWriteAt(pDisk->hVfsFile, off, pvBuf, cbWrite, NULL /*pcbWritten*/); +} + +extern DECL_HIDDEN_DATA(const RTDVMFMTOPS) g_rtDvmFmtMbr; +extern DECL_HIDDEN_DATA(const RTDVMFMTOPS) g_rtDvmFmtGpt; +extern DECL_HIDDEN_DATA(const RTDVMFMTOPS) g_rtDvmFmtBsdLbl; + +RT_C_DECLS_END + +#endif /* !IPRT_INCLUDED_INTERNAL_dvm_h */ + diff --git a/src/VBox/Runtime/include/internal/file.h b/src/VBox/Runtime/include/internal/file.h new file mode 100644 index 00000000..83ff0693 --- /dev/null +++ b/src/VBox/Runtime/include/internal/file.h @@ -0,0 +1,93 @@ +/* $Id: file.h $ */ +/** @file + * IPRT - Internal RTFile header. + */ + +/* + * Copyright (C) 2006-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_INTERNAL_file_h +#define IPRT_INCLUDED_INTERNAL_file_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/file.h> + +RT_C_DECLS_BEGIN + +/** + * Adjusts and validates the flags. + * + * The adjustments are made according to the wishes specified using the RTFileSetForceFlags API. + * + * @returns IPRT status code. + * @param pfOpen Pointer to the user specified flags on input. + * Updated on successful return. + * @internal + */ +int rtFileRecalcAndValidateFlags(uint64_t *pfOpen); + + +/** + * Internal interface for getting the RTFILE handle of stdin, stdout or stderr. + * + * This interface will not be exposed and is purely for internal IPRT use. + * + * @returns Handle or NIL_RTFILE. + * + * @param enmStdHandle The standard handle. + */ +RTFILE rtFileGetStandard(RTHANDLESTD enmStdHandle); + +#ifdef RT_OS_WINDOWS +/** + * Helper for converting RTFILE_O_XXX to the various NtCreateFile flags. + * + * @returns IPRT status code + * @param fOpen The RTFILE_O_XXX flags to convert. + * @param pfDesiredAccess Where to return the desired access mask. + * @param pfObjAttribs Where to return the NT object attributes. + * @param pfFileAttribs Where to return the file attributes (create). + * @param pfShareAccess Where to return the file sharing access mask. + * @param pfCreateDisposition Where to return the file create disposition. + * @param pfCreateOptions Where to return the file open/create options. + */ +DECLHIDDEN(int) rtFileNtValidateAndConvertFlags(uint64_t fOpen, uint32_t *pfDesiredAccess, uint32_t *pfObjAttribs, + uint32_t *pfFileAttribs, uint32_t *pfShareAccess, uint32_t *pfCreateDisposition, + uint32_t *pfCreateOptions); + +#endif + +RT_C_DECLS_END + +#endif /* !IPRT_INCLUDED_INTERNAL_file_h */ + diff --git a/src/VBox/Runtime/include/internal/fileaio.h b/src/VBox/Runtime/include/internal/fileaio.h new file mode 100644 index 00000000..9e718746 --- /dev/null +++ b/src/VBox/Runtime/include/internal/fileaio.h @@ -0,0 +1,133 @@ +/* $Id: fileaio.h $ */ +/** @file + * IPRT - Internal RTFileAio header. + */ + +/* + * Copyright (C) 2009-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_INTERNAL_fileaio_h +#define IPRT_INCLUDED_INTERNAL_fileaio_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/file.h> +#include "internal/magics.h" + +/******************************************************************************* +* Structures and Typedefs * +*******************************************************************************/ +/** + * Defined request states. + */ +typedef enum RTFILEAIOREQSTATE +{ + /** Prepared. */ + RTFILEAIOREQSTATE_PREPARED = 0, + /** Submitted. */ + RTFILEAIOREQSTATE_SUBMITTED, + /** Completed. */ + RTFILEAIOREQSTATE_COMPLETED, + /** Omni present 32bit hack. */ + RTFILEAIOREQSTATE_32BIT_HACK = 0x7fffffff +} RTFILEAIOREQSTATE; + +/******************************************************************************* +* Defined Constants And Macros * +*******************************************************************************/ + +/** Return true if the specified request is not valid, false otherwise. */ +#define RTFILEAIOREQ_IS_NOT_VALID(pReq) \ + (RT_UNLIKELY(!RT_VALID_PTR(pReq) || (pReq->u32Magic != RTFILEAIOREQ_MAGIC))) + +/** Validates a context handle and returns VERR_INVALID_HANDLE if not valid. */ +#define RTFILEAIOREQ_VALID_RETURN_RC(pReq, rc) \ + do { \ + AssertPtrReturn((pReq), (rc)); \ + AssertReturn((pReq)->u32Magic == RTFILEAIOREQ_MAGIC, (rc)); \ + } while (0) + +/** Validates a context handle and returns VERR_INVALID_HANDLE if not valid. */ +#define RTFILEAIOREQ_VALID_RETURN(pReq) RTFILEAIOREQ_VALID_RETURN_RC((pReq), VERR_INVALID_HANDLE) + +/** Validates a context handle and returns (void) if not valid. */ +#define RTFILEAIOREQ_VALID_RETURN_VOID(pReq) \ + do { \ + AssertPtrReturnVoid(pReq); \ + AssertReturnVoid((pReq)->u32Magic == RTFILEAIOREQ_MAGIC); \ + } while (0) + +/** Validates a context handle and returns the specified rc if not valid. */ +#define RTFILEAIOCTX_VALID_RETURN_RC(pCtx, rc) \ + do { \ + AssertPtrReturn((pCtx), (rc)); \ + AssertReturn((pCtx)->u32Magic == RTFILEAIOCTX_MAGIC, (rc)); \ + } while (0) + +/** Validates a context handle and returns VERR_INVALID_HANDLE if not valid. */ +#define RTFILEAIOCTX_VALID_RETURN(pCtx) RTFILEAIOCTX_VALID_RETURN_RC((pCtx), VERR_INVALID_HANDLE) + +/** Checks if a request is in the specified state and returns the specified rc if not. */ +#define RTFILEAIOREQ_STATE_RETURN_RC(pReq, State, rc) \ + do { \ + if (RT_UNLIKELY(pReq->enmState != RTFILEAIOREQSTATE_##State)) \ + return rc; \ + } while (0) + +/** Checks if a request is not in the specified state and returns the specified rc if it is. */ +#define RTFILEAIOREQ_NOT_STATE_RETURN_RC(pReq, State, rc) \ + do { \ + if (RT_UNLIKELY(pReq->enmState == RTFILEAIOREQSTATE_##State)) \ + return rc; \ + } while (0) + +/** Checks if a request in the given states and sserts if not. */ +#define RTFIELAIOREQ_ASSERT_STATE(pReq, State) \ + do { \ + AssertPtr((pReq)); \ + Assert((pReq)->u32Magic == RTFILEAIOREQ_MAGIC); \ + Assert((pReq)->enmState == RTFILEAIOREQSTATE_##State); \ + } while (0) + +/** Sets the request into a specific state. */ +#define RTFILEAIOREQ_SET_STATE(pReq, State) \ + do { \ + pReq->enmState = RTFILEAIOREQSTATE_##State; \ + } while (0) + + +RT_C_DECLS_BEGIN + +RT_C_DECLS_END + +#endif /* !IPRT_INCLUDED_INTERNAL_fileaio_h */ + diff --git a/src/VBox/Runtime/include/internal/fs.h b/src/VBox/Runtime/include/internal/fs.h new file mode 100644 index 00000000..c703670e --- /dev/null +++ b/src/VBox/Runtime/include/internal/fs.h @@ -0,0 +1,96 @@ +/* $Id: fs.h $ */ +/** @file + * IPRT - Internal RTFs header. + */ + +/* + * Copyright (C) 2006-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_INTERNAL_fs_h +#define IPRT_INCLUDED_INTERNAL_fs_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/types.h> +#ifndef RT_OS_WINDOWS +# include <sys/stat.h> +#endif +#ifdef RT_OS_FREEBSD +# include <osreldate.h> +#endif + +RT_C_DECLS_BEGIN + +/** IO_REPARSE_TAG_SYMLINK */ +#define RTFSMODE_SYMLINK_REPARSE_TAG UINT32_C(0xa000000c) + +RTFMODE rtFsModeFromDos(RTFMODE fMode, const char *pszName, size_t cbName, uint32_t uReparseTag, RTFMODE fType); +RTFMODE rtFsModeFromUnix(RTFMODE fMode, const char *pszName, size_t cbName, RTFMODE fType); +RTFMODE rtFsModeNormalize(RTFMODE fMode, const char *pszName, size_t cbName, RTFMODE fType); +bool rtFsModeIsValid(RTFMODE fMode); +bool rtFsModeIsValidPermissions(RTFMODE fMode); + +#ifndef RT_OS_WINDOWS +void rtFsConvertStatToObjInfo(PRTFSOBJINFO pObjInfo, const struct stat *pStat, const char *pszName, unsigned cbName); +void rtFsObjInfoAttrSetUnixOwner(PRTFSOBJINFO pObjInfo, RTUID uid); +void rtFsObjInfoAttrSetUnixGroup(PRTFSOBJINFO pObjInfo, RTUID gid); +#else /* RT_OS_WINDOWS */ +# ifdef DECLARE_HANDLE +int rtNtQueryFsType(HANDLE hHandle, PRTFSTYPE penmType); +# endif +#endif /* RT_OS_WINDOWS */ + +#ifdef RT_OS_LINUX +# ifdef __USE_MISC +# define HAVE_STAT_TIMESPEC_BRIEF +# else +# define HAVE_STAT_NSEC +# endif +#endif + +#ifdef RT_OS_FREEBSD +# if __FreeBSD_version >= 500000 /* 5.0 */ +# define HAVE_STAT_BIRTHTIME +# endif +# if __FreeBSD_version >= 900000 /* 9.0 */ +# define HAVE_STAT_TIMESPEC_BRIEF +# else +# ifndef __BSD_VISIBLE +# define __BSD_VISIBLE +# endif +# define HAVE_STAT_TIMESPEC +# endif +#endif + +RT_C_DECLS_END + +#endif /* !IPRT_INCLUDED_INTERNAL_fs_h */ diff --git a/src/VBox/Runtime/include/internal/initterm.h b/src/VBox/Runtime/include/internal/initterm.h new file mode 100644 index 00000000..8c3ea527 --- /dev/null +++ b/src/VBox/Runtime/include/internal/initterm.h @@ -0,0 +1,82 @@ +/* $Id: initterm.h $ */ +/** @file + * IPRT - Initialization & Termination. + */ + +/* + * Copyright (C) 2006-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_INTERNAL_initterm_h +#define IPRT_INCLUDED_INTERNAL_initterm_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/cdefs.h> + +RT_C_DECLS_BEGIN + +#ifdef IN_RING0 + +/** + * Platform specific initialization. + * + * @returns IPRT status code. + */ +DECLHIDDEN(int) rtR0InitNative(void); + +/** + * Platform specific termination. + */ +DECLHIDDEN(void) rtR0TermNative(void); + +#endif /* IN_RING0 */ + +#ifdef IN_RING3 + +extern DECL_HIDDEN_DATA(int32_t volatile) g_crtR3Users; +extern DECL_HIDDEN_DATA(bool volatile) g_frtR3Initializing; +extern DECL_HIDDEN_DATA(bool volatile) g_frtAtExitCalled; + +/** + * Internal version of RTR3InitIsInitialized. + */ +DECLINLINE(bool) rtInitIsInitialized(void) +{ + return g_crtR3Users >= 1 && !g_frtR3Initializing; +} + +#endif + +RT_C_DECLS_END + +#endif /* !IPRT_INCLUDED_INTERNAL_initterm_h */ + diff --git a/src/VBox/Runtime/include/internal/ioqueue.h b/src/VBox/Runtime/include/internal/ioqueue.h new file mode 100644 index 00000000..1d6926b8 --- /dev/null +++ b/src/VBox/Runtime/include/internal/ioqueue.h @@ -0,0 +1,62 @@ +/* $Id: ioqueue.h $ */ +/** @file + * IPRT - Internal RTIoQueue header. + */ + +/* + * Copyright (C) 2019-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_INTERNAL_ioqueue_h +#define IPRT_INCLUDED_INTERNAL_ioqueue_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/ioqueue.h> + +RT_C_DECLS_BEGIN + +/** The standard file I/O queue provider using synchronous file access. */ +extern RTDATADECL(RTIOQUEUEPROVVTABLE const) g_RTIoQueueStdFileProv; +#ifndef RT_OS_OS2 +/** The file I/O queue provider using the RTFileAio API. */ +extern RTDATADECL(RTIOQUEUEPROVVTABLE const) g_RTIoQueueAioFileProv; +#endif +#if defined(RT_OS_LINUX) +/** The file I/O queue provider using the recently added io_uring interface when + * available on the host. */ +extern RTDATADECL(RTIOQUEUEPROVVTABLE const) g_RTIoQueueLnxIoURingProv; +#endif + +RT_C_DECLS_END + +#endif /* !IPRT_INCLUDED_INTERNAL_ioqueue_h */ + diff --git a/src/VBox/Runtime/include/internal/iprt-openssl.h b/src/VBox/Runtime/include/internal/iprt-openssl.h new file mode 100644 index 00000000..1c02b0e5 --- /dev/null +++ b/src/VBox/Runtime/include/internal/iprt-openssl.h @@ -0,0 +1,66 @@ +/* $Id: iprt-openssl.h $ */ +/** @file + * IPRT - Internal header for the OpenSSL helpers. + */ + +/* + * Copyright (C) 2006-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_INTERNAL_iprt_openssl_h +#define IPRT_INCLUDED_INTERNAL_iprt_openssl_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/crypto/x509.h> +#include <iprt/crypto/pkcs7.h> + +RT_C_DECLS_BEGIN +struct evp_md_st; +struct evp_pkey_st; + +DECLHIDDEN(void) rtCrOpenSslInit(void); +DECLHIDDEN(int) rtCrOpenSslErrInfoCallback(const char *pach, size_t cch, void *pvUser); +DECLHIDDEN(int) rtCrOpenSslConvertX509Cert(void **ppvOsslCert, PCRTCRX509CERTIFICATE pCert, PRTERRINFO pErrInfo); +DECLHIDDEN(void) rtCrOpenSslFreeConvertedX509Cert(void *pvOsslCert); +DECLHIDDEN(int) rtCrOpenSslAddX509CertToStack(void *pvOsslStack, PCRTCRX509CERTIFICATE pCert, PRTERRINFO pErrInfo); +DECLHIDDEN(const void /*EVP_MD*/ *) rtCrOpenSslConvertDigestType(RTDIGESTTYPE enmDigestType, PRTERRINFO pErrInfo); +DECLHIDDEN(int) rtCrOpenSslConvertPkcs7Attribute(void **ppvOsslAttrib, PCRTCRPKCS7ATTRIBUTE pAttrib, PRTERRINFO pErrInfo); +DECLHIDDEN(void) rtCrOpenSslFreeConvertedPkcs7Attribute(void *pvOsslAttrib); + +DECLHIDDEN(int) rtCrKeyToOpenSslKey(RTCRKEY hKey, bool fNeedPublic, void /*EVP_PKEY*/ **ppEvpKey, PRTERRINFO pErrInfo); +DECLHIDDEN(int) rtCrKeyToOpenSslKeyEx(RTCRKEY hKey, bool fNeedPublic, const char *pszAlgoObjId, + void /*EVP_PKEY*/ **ppEvpKey, const void /*EVP_MD*/ **ppEvpMdType, PRTERRINFO pErrInfo); + +RT_C_DECLS_END + +#endif /* !IPRT_INCLUDED_INTERNAL_iprt_openssl_h */ + diff --git a/src/VBox/Runtime/include/internal/iprt.h b/src/VBox/Runtime/include/internal/iprt.h new file mode 100644 index 00000000..d1197009 --- /dev/null +++ b/src/VBox/Runtime/include/internal/iprt.h @@ -0,0 +1,258 @@ +/* $Id: iprt.h $ */ +/** @file + * IPRT - Internal header for miscellaneous global defs and types. + */ + +/* + * Copyright (C) 2009-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_INTERNAL_iprt_h +#define IPRT_INCLUDED_INTERNAL_iprt_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/cdefs.h> +#include <iprt/types.h> + +/** @def RT_EXPORT_SYMBOL + * This define is really here just for the linux kernel. + * @param Name The symbol name. + */ +#if defined(RT_OS_LINUX) \ + && defined(IN_RING0) \ + && defined(MODULE) \ + && !defined(RT_NO_EXPORT_SYMBOL) +# define bool linux_bool /* see r0drv/linux/the-linux-kernel.h */ +# include <linux/version.h> +# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33) +# include <generated/autoconf.h> +# else +# ifndef AUTOCONF_INCLUDED +# include <linux/autoconf.h> +# endif +# endif +# if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS) +# define MODVERSIONS +# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 71) +# include <linux/modversions.h> +# endif +# endif +# include <linux/module.h> +# undef bool +# define RT_EXPORT_SYMBOL(Name) EXPORT_SYMBOL(Name) +#else +# define RT_EXPORT_SYMBOL(Name) extern int g_rtExportSymbolDummyVariable +#endif + +/** @def RT_ALIAS_AND_EXPORT_NOCRT_SYMBOL + * Creates symbol alias and export a RT_NOCRT symbol. + * + * For targets using ELF this macro generates weak symbol aliases, for the other + * object formats the makefile scans source files for this macro and produces + * separate object files with the aliases. + * + * @param a_Name The CRT function or variable name. + * + * @todo Does not support ELF targets using underscore prefixed symbols. + */ +#if defined(__ELF__) && defined(RT_WITH_NOCRT_ALIASES) && !defined(RT_WITHOUT_NOCRT_ALIASES) +# ifdef RT_WITH_NOCRT_UNDERSCORE_ALIASES +# define RT_ALIAS_AND_EXPORT_NOCRT_SYMBOL(a_Name) RT_EXPORT_SYMBOL(a_Name) \ + __asm__(".weak " #a_Name "\n\t" \ + ".set " #a_Name "," RT_NOCRT_STR(a_Name) "\n\t" \ + ".weak _" #a_Name "\n\t" \ + ".set _" #a_Name "," RT_NOCRT_STR(a_Name) "\n\t") +# else +# define RT_ALIAS_AND_EXPORT_NOCRT_SYMBOL(a_Name) RT_EXPORT_SYMBOL(a_Name) \ + __asm__(".weak " #a_Name "\n\t" \ + ".set " #a_Name "," RT_NOCRT_STR(a_Name) "\n\t") +# endif +#else +# define RT_ALIAS_AND_EXPORT_NOCRT_SYMBOL(a_Name) RT_EXPORT_SYMBOL(a_Name) +#endif + +/** @def RT_ALIAS_AND_EXPORT_NOCRT_SYMBOL_WITHOUT_UNDERSCORE + * Variant of RT_ALIAS_AND_EXPORT_NOCRT_SYMBOL that omits the + * underscore-prefixed variant of the symbol. + * + * @param a_Name The CRT function or variable name. + */ +#if defined(__ELF__) && defined(RT_WITH_NOCRT_ALIASES) && !defined(RT_WITHOUT_NOCRT_ALIASES) +# define RT_ALIAS_AND_EXPORT_NOCRT_SYMBOL_WITHOUT_UNDERSCORE(a_Name) RT_EXPORT_SYMBOL(a_Name) \ + __asm__(".weak " #a_Name "\n\t" \ + ".set " #a_Name "," RT_NOCRT_STR(a_Name) "\n\t") +#else +# define RT_ALIAS_AND_EXPORT_NOCRT_SYMBOL_WITHOUT_UNDERSCORE(a_Name) RT_EXPORT_SYMBOL(a_Name) +#endif + + +/** @def RT_MORE_STRICT + * Enables more assertions in IPRT. */ +#if !defined(RT_MORE_STRICT) && (defined(DEBUG) || defined(RT_STRICT) || defined(DOXYGEN_RUNNING)) && !defined(RT_OS_WINDOWS) /** @todo enable on windows after testing */ +# define RT_MORE_STRICT +#endif + +/** @def RT_ASSERT_PREEMPT_CPUID_VAR + * Partner to RT_ASSERT_PREEMPT_CPUID_VAR. Declares and initializes a variable + * idAssertCpu to NIL_RTCPUID if preemption is enabled and to RTMpCpuId if + * disabled. When RT_MORE_STRICT isn't defined it declares an uninitialized + * dummy variable. + * + * Requires iprt/mp.h and iprt/asm.h. + */ +/** @def RT_ASSERT_PREEMPT_CPUID + * Asserts that we didn't change CPU since RT_ASSERT_PREEMPT_CPUID_VAR if + * preemption is disabled. Will also detect changes in preemption + * disable/enable status. This is a noop when RT_MORE_STRICT isn't defined. */ +#ifdef RT_MORE_STRICT +# define RT_ASSERT_PREEMPT_CPUID_VAR() \ + RTCPUID const idAssertCpu = RTThreadPreemptIsEnabled(NIL_RTTHREAD) ? NIL_RTCPUID : RTMpCpuId() +# define RT_ASSERT_PREEMPT_CPUID() \ + do \ + { \ + RTCPUID const idAssertCpuNow = RTThreadPreemptIsEnabled(NIL_RTTHREAD) ? NIL_RTCPUID : RTMpCpuId(); \ + AssertMsg(idAssertCpu == idAssertCpuNow, ("%#x, %#x\n", idAssertCpu, idAssertCpuNow)); \ + } while (0) + +#else +# define RT_ASSERT_PREEMPT_CPUID_VAR() RTCPUID idAssertCpuDummy +# define RT_ASSERT_PREEMPT_CPUID() NOREF(idAssertCpuDummy) +#endif + +/** @def RT_ASSERT_PREEMPT_CPUID_SPIN_ACQUIRED + * Extended version of RT_ASSERT_PREEMPT_CPUID for use before + * RTSpinlockAcquired* returns. This macro works the idCpuOwner and idAssertCpu + * members of the spinlock instance data. */ +#ifdef RT_MORE_STRICT +# define RT_ASSERT_PREEMPT_CPUID_SPIN_ACQUIRED(pThis) \ + do \ + { \ + RTCPUID const idAssertCpuNow = RTMpCpuId(); \ + AssertMsg(idAssertCpu == idAssertCpuNow || idAssertCpu == NIL_RTCPUID, ("%#x, %#x\n", idAssertCpu, idAssertCpuNow)); \ + (pThis)->idAssertCpu = idAssertCpu; \ + (pThis)->idCpuOwner = idAssertCpuNow; \ + } while (0) +#else +# define RT_ASSERT_PREEMPT_CPUID_SPIN_ACQUIRED(pThis) NOREF(idAssertCpuDummy) +#endif + +/** @def RT_ASSERT_PREEMPT_CPUID_SPIN_RELEASE_VARS + * Extended version of RT_ASSERT_PREEMPT_CPUID_VAR for use with + * RTSpinlockRelease* returns. */ +#ifdef RT_MORE_STRICT +# define RT_ASSERT_PREEMPT_CPUID_SPIN_RELEASE_VARS() RTCPUID idAssertCpu +#else +# define RT_ASSERT_PREEMPT_CPUID_SPIN_RELEASE_VARS() RTCPUID idAssertCpuDummy +#endif + +/** @def RT_ASSERT_PREEMPT_CPUID_SPIN_RELEASE + * Extended version of RT_ASSERT_PREEMPT_CPUID for use in RTSpinlockRelease* + * before calling the native API for releasing the spinlock. It must be + * teamed up with RT_ASSERT_PREEMPT_CPUID_SPIN_ACQUIRED. */ +#ifdef RT_MORE_STRICT +# define RT_ASSERT_PREEMPT_CPUID_SPIN_RELEASE(pThis) \ + do \ + { \ + RTCPUID const idCpuOwner = (pThis)->idCpuOwner; \ + RTCPUID const idAssertCpuNow = RTMpCpuId(); \ + AssertMsg(idCpuOwner == idAssertCpuNow, ("%#x, %#x\n", idCpuOwner, idAssertCpuNow)); \ + (pThis)->idCpuOwner = NIL_RTCPUID; \ + idAssertCpu = (pThis)->idAssertCpu; \ + (pThis)->idAssertCpu = NIL_RTCPUID; \ + } while (0) +#else +# define RT_ASSERT_PREEMPT_CPUID_SPIN_RELEASE(pThis) NOREF(idAssertCpuDummy) +#endif + +/** @def RT_ASSERT_PREEMPT_CPUID_DISABLE + * For use in RTThreadPreemptDisable implementations after having disabled + * preemption. Requires iprt/mp.h. */ +#ifdef RT_MORE_STRICT +# define RT_ASSERT_PREEMPT_CPUID_DISABLE(pStat) \ + do \ + { \ + Assert((pStat)->idCpu == NIL_RTCPUID); \ + (pStat)->idCpu = RTMpCpuId(); \ + } while (0) +#else +# define RT_ASSERT_PREEMPT_CPUID_DISABLE(pStat) \ + Assert((pStat)->idCpu == NIL_RTCPUID) +#endif + +/** @def RT_ASSERT_PREEMPT_CPUID_RESTORE + * For use in RTThreadPreemptRestore implementations before restoring + * preemption. Requires iprt/mp.h. */ +#ifdef RT_MORE_STRICT +# define RT_ASSERT_PREEMPT_CPUID_RESTORE(pStat) \ + do \ + { \ + RTCPUID const idAssertCpuNow = RTMpCpuId(); \ + AssertMsg((pStat)->idCpu == idAssertCpuNow, ("%#x, %#x\n", (pStat)->idCpu, idAssertCpuNow)); \ + (pStat)->idCpu = NIL_RTCPUID; \ + } while (0) +#else +# define RT_ASSERT_PREEMPT_CPUID_RESTORE(pStat) do { } while (0) +#endif + + +/** @def RT_ASSERT_INTS_ON + * Asserts that interrupts are disabled when RT_MORE_STRICT is defined. */ +#ifdef RT_MORE_STRICT +# if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86) +# define RT_ASSERT_INTS_ON() Assert(ASMIntAreEnabled()) +# else /* PORTME: Add architecture/platform specific test. */ +# define RT_ASSERT_INTS_ON() Assert(RTThreadPreemptIsEnabled(NIL_RTTHREAD)) +# endif +#else +# define RT_ASSERT_INTS_ON() do { } while (0) +#endif + +/** @def RT_ASSERT_PREEMPTIBLE + * Asserts that preemption hasn't been disabled (using + * RTThreadPreemptDisable) when RT_MORE_STRICT is defined. */ +#ifdef RT_MORE_STRICT +# define RT_ASSERT_PREEMPTIBLE() Assert(RTThreadPreemptIsEnabled(NIL_RTTHREAD)) +#else +# define RT_ASSERT_PREEMPTIBLE() do { } while (0) +#endif + + +RT_C_DECLS_BEGIN + +#ifdef RT_OS_OS2 +uint32_t rtR0SemWaitOs2ConvertTimeout(uint32_t fFlags, uint64_t uTimeout); +#endif + +RT_C_DECLS_END + +#endif /* !IPRT_INCLUDED_INTERNAL_iprt_h */ + diff --git a/src/VBox/Runtime/include/internal/ldr.h b/src/VBox/Runtime/include/internal/ldr.h new file mode 100644 index 00000000..f48796eb --- /dev/null +++ b/src/VBox/Runtime/include/internal/ldr.h @@ -0,0 +1,658 @@ +/* $Id: ldr.h $ */ +/** @file + * IPRT - Loader Internals. + */ + +/* + * Copyright (C) 2006-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_INTERNAL_ldr_h +#define IPRT_INCLUDED_INTERNAL_ldr_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/types.h> +#include "internal/magics.h" + +RT_C_DECLS_BEGIN + + +/******************************************************************************* +* Defined Constants And Macros * +*******************************************************************************/ +#ifdef DOXYGEN_RUNNING +/** @def LDR_WITH_NATIVE + * Define this to get native support. */ +# define LDR_WITH_NATIVE + +/** @def LDR_WITH_ELF32 + * Define this to get 32-bit ELF support. */ +# define LDR_WITH_ELF32 + +/** @def LDR_WITH_ELF64 + * Define this to get 64-bit ELF support. */ +# define LDR_WITH_ELF64 + +/** @def LDR_WITH_PE + * Define this to get 32-bit and 64-bit PE support. */ +# define LDR_WITH_PE + +/** @def LDR_WITH_LX + * Define this to get LX support. */ +# define LDR_WITH_LX + +/** @def LDR_WITH_MACHO + * Define this to get mach-o support (not implemented yet). */ +# define LDR_WITH_MACHO +#endif /* DOXYGEN_RUNNING */ + +#if defined(LDR_WITH_ELF32) || defined(LDR_WITH_ELF64) +/** @def LDR_WITH_ELF + * This is defined if any of the ELF versions is requested. + */ +# define LDR_WITH_ELF +#endif + +/* These two may clash with winnt.h. */ +#undef IMAGE_DOS_SIGNATURE +#undef IMAGE_NT_SIGNATURE +#undef IMAGE_LX_SIGNATURE + + +/** Little endian uint32_t ELF signature ("\x7fELF"). */ +#define IMAGE_ELF_SIGNATURE (0x7f | ('E' << 8) | ('L' << 16) | ('F' << 24)) +/** Little endian uint32_t PE signature ("PE\0\0"). */ +#define IMAGE_NT_SIGNATURE 0x00004550 +/** Little endian uint16_t LX signature ("LX") */ +#define IMAGE_LX_SIGNATURE ('L' | ('X' << 8)) +/** Little endian uint16_t LE signature ("LE") */ +#define IMAGE_LE_SIGNATURE ('L' | ('E' << 8)) +/** Little endian uint16_t NE signature ("NE") */ +#define IMAGE_NE_SIGNATURE ('N' | ('E' << 8)) +/** Little endian uint16_t MZ signature ("MZ"). */ +#define IMAGE_DOS_SIGNATURE ('M' | ('Z' << 8)) + + +/** Kind of missing flag. */ +#define RTMEM_PROT_WRITECOPY RTMEM_PROT_WRITE + + +/** @name Load symbol kind flags (from kStuff, expose later). + * @{ */ +/** The bitness doesn't matter. */ +#define RTLDRSYMKIND_NO_BIT UINT32_C(0x00000000) +/** 16-bit symbol. */ +#define RTLDRSYMKIND_16BIT UINT32_C(0x00000001) +/** 32-bit symbol. */ +#define RTLDRSYMKIND_32BIT UINT32_C(0x00000002) +/** 64-bit symbol. */ +#define RTLDRSYMKIND_64BIT UINT32_C(0x00000003) +/** Mask out the bit.*/ +#define RTLDRSYMKIND_BIT_MASK UINT32_C(0x00000003) +/** We don't know the type of symbol. */ +#define RTLDRSYMKIND_NO_TYPE UINT32_C(0x00000000) +/** The symbol is a code object (method/function/procedure/whateveryouwannacallit). */ +#define RTLDRSYMKIND_CODE UINT32_C(0x00000010) +/** The symbol is a data object. */ +#define RTLDRSYMKIND_DATA UINT32_C(0x00000020) +/** Mask out the symbol type. */ +#define RTLDRSYMKIND_TYPE_MASK UINT32_C(0x00000030) +/** Valid symbol kind mask. */ +#define RTLDRSYMKIND_MASK UINT32_C(0x00000033) +/** Weak symbol. */ +#define RTLDRSYMKIND_WEAK UINT32_C(0x00000100) +/** Forwarder symbol. */ +#define RTLDRSYMKIND_FORWARDER UINT32_C(0x00000200) +/** Request a flat symbol address. */ +#define RTLDRSYMKIND_REQ_FLAT UINT32_C(0x00000000) +/** Request a segmented symbol address. */ +#define RTLDRSYMKIND_REQ_SEGMENTED UINT32_C(0x40000000) +/** Request type mask. */ +#define RTLDRSYMKIND_REQ_TYPE_MASK UINT32_C(0x40000000) +/** @} */ + +/** Align a RTLDRADDR value. */ +#define RTLDR_ALIGN_ADDR(val, align) ( ((val) + ((align) - 1)) & ~(RTLDRADDR)((align) - 1) ) + +/** Special base address value alias for the link address. + * Consider propagating... */ +#define RTLDR_BASEADDRESS_LINK (~(RTLDRADDR)1) + + + +/******************************************************************************* +* Structures and Typedefs * +*******************************************************************************/ +/** + * Loader state. + */ +typedef enum RTLDRSTATE +{ + /** Invalid. */ + LDR_STATE_INVALID = 0, + /** Opened. */ + LDR_STATE_OPENED, + /** The image can no longer be relocated. */ + LDR_STATE_DONE, + /** The image was loaded, not opened. */ + LDR_STATE_LOADED, + /** The usual 32-bit hack. */ + LDR_STATE_32BIT_HACK = 0x7fffffff +} RTLDRSTATE; + + +/** + * CPU models (from kStuff, expose later some time). + */ +typedef enum RTLDRCPU +{ + /** The usual invalid cpu. */ + RTLDRCPU_INVALID = 0, + + /** @name K_ARCH_X86_16 + * @{ */ + RTLDRCPU_I8086, + RTLDRCPU_I8088, + RTLDRCPU_I80186, + RTLDRCPU_I80286, + RTLDRCPU_I386_16, + RTLDRCPU_I486_16, + RTLDRCPU_I486SX_16, + RTLDRCPU_I586_16, + RTLDRCPU_I686_16, + RTLDRCPU_P4_16, + RTLDRCPU_CORE2_16, + RTLDRCPU_K6_16, + RTLDRCPU_K7_16, + RTLDRCPU_K8_16, + RTLDRCPU_FIRST_X86_16 = RTLDRCPU_I8086, + RTLDRCPU_LAST_X86_16 = RTLDRCPU_K8_16, + /** @} */ + + /** @name K_ARCH_X86_32 + * @{ */ + RTLDRCPU_X86_32_BLEND, + RTLDRCPU_I386, + RTLDRCPU_I486, + RTLDRCPU_I486SX, + RTLDRCPU_I586, + RTLDRCPU_I686, + RTLDRCPU_P4, + RTLDRCPU_CORE2_32, + RTLDRCPU_K6, + RTLDRCPU_K7, + RTLDRCPU_K8_32, + RTLDRCPU_FIRST_X86_32 = RTLDRCPU_I386, + RTLDRCPU_LAST_X86_32 = RTLDRCPU_K8_32, + /** @} */ + + /** @name K_ARCH_AMD64 + * @{ */ + RTLDRCPU_AMD64_BLEND, + RTLDRCPU_K8, + RTLDRCPU_P4_64, + RTLDRCPU_CORE2, + RTLDRCPU_FIRST_AMD64 = RTLDRCPU_K8, + RTLDRCPU_LAST_AMD64 = RTLDRCPU_CORE2, + /** @} */ + + /** @name K_ARCH_ARM64 + * @{ */ + RTLDRCPU_ARM64_BLEND, + RTLDRCPU_ARM64_V8, + RTLDRCPU_ARM64E, + RTLDRCPU_FIRST_ARM64 = RTLDRCPU_ARM64_V8, + RTLDRCPU_LAST_ARM64 = RTLDRCPU_ARM64E, + /** @} */ + + /** The end of the valid cpu values (exclusive). */ + RTLDRCPU_END, + /** Hack to blow the type up to 32-bit. */ + RTLDRCPU_32BIT_HACK = 0x7fffffff +} RTLDRCPU; + + +/** Pointer to a loader item. */ +typedef struct RTLDRMODINTERNAL *PRTLDRMODINTERNAL; + +/** + * Loader module operations. + */ +typedef struct RTLDROPS +{ + /** The name of the executable format. */ + const char *pszName; + + /** + * Release any resources attached to the module. + * The caller will do RTMemFree on pMod on return. + * + * @returns iprt status code. + * @param pMod Pointer to the loader module structure. + * @remark Compulsory entry point. + */ + DECLCALLBACKMEMBER(int, pfnClose,(PRTLDRMODINTERNAL pMod)); + + /** + * Gets a simple symbol. + * This entrypoint can be omitted if RTLDROPS::pfnGetSymbolEx() is provided. + * + * @returns iprt status code. + * @param pMod Pointer to the loader module structure. + * @param pszSymbol The symbol name. + * @param ppvValue Where to store the symbol value. + */ + DECLCALLBACKMEMBER(int, pfnGetSymbol,(PRTLDRMODINTERNAL pMod, const char *pszSymbol, void **ppvValue)); + + /** + * Called when we're done with getting bits and relocating them. + * This is used to release resources used by the loader to support those actions. + * + * After this call none of the extended loader functions can be called. + * + * @returns iprt status code. + * @param pMod Pointer to the loader module structure. + * @remark This is an optional entry point. + */ + DECLCALLBACKMEMBER(int, pfnDone,(PRTLDRMODINTERNAL pMod)); + + /** + * Enumerates the symbols exported by the module. + * + * @returns iprt status code, which might have been returned by pfnCallback. + * @param pMod Pointer to the loader module structure. + * @param fFlags Flags indicating what to return and such. + * @param pvBits Pointer to the bits returned by RTLDROPS::pfnGetBits(), optional. + * @param BaseAddress The image base addressto use when calculating the symbol values. + * @param pfnCallback The callback function which each symbol is to be + * fed to. + * @param pvUser User argument to pass to the enumerator. + * @remark This is an optional entry point. + */ + DECLCALLBACKMEMBER(int, pfnEnumSymbols,(PRTLDRMODINTERNAL pMod, unsigned fFlags, const void *pvBits, RTUINTPTR BaseAddress, + PFNRTLDRENUMSYMS pfnCallback, void *pvUser)); + + +/* extended functions: */ + + /** + * Gets the size of the loaded image (i.e. in memory). + * + * @returns in memory size, in bytes. + * @returns ~(size_t)0 if it's not an extended image. + * @param pMod Pointer to the loader module structure. + * @remark Extended loader feature. + */ + DECLCALLBACKMEMBER(size_t, pfnGetImageSize,(PRTLDRMODINTERNAL pMod)); + + /** + * Gets the image bits fixed up for a specified address. + * + * @returns iprt status code. + * @param pMod Pointer to the loader module structure. + * @param pvBits Where to store the bits. The size of this buffer is equal or + * larger to the value returned by pfnGetImageSize(). + * @param BaseAddress The base address which the image should be fixed up to. + * @param pfnGetImport The callback function to use to resolve imports (aka unresolved externals). + * @param pvUser User argument to pass to the callback. + * @remark Extended loader feature. + */ + DECLCALLBACKMEMBER(int, pfnGetBits,(PRTLDRMODINTERNAL pMod, void *pvBits, RTUINTPTR BaseAddress, PFNRTLDRIMPORT pfnGetImport, void *pvUser)); + + /** + * Relocate bits obtained using pfnGetBits to a new address. + * + * @returns iprt status code. + * @param pMod Pointer to the loader module structure. + * @param pvBits Where to store the bits. The size of this buffer is equal or + * larger to the value returned by pfnGetImageSize(). + * @param NewBaseAddress The base address which the image should be fixed up to. + * @param OldBaseAddress The base address which the image is currently fixed up to. + * @param pfnGetImport The callback function to use to resolve imports (aka unresolved externals). + * @param pvUser User argument to pass to the callback. + * @remark Extended loader feature. + */ + DECLCALLBACKMEMBER(int, pfnRelocate,(PRTLDRMODINTERNAL pMod, void *pvBits, RTUINTPTR NewBaseAddress, RTUINTPTR OldBaseAddress, PFNRTLDRIMPORT pfnGetImport, void *pvUser)); + + /** + * Gets a symbol with special base address and stuff. + * This entrypoint can be omitted if RTLDROPS::pfnGetSymbolEx() is provided and the special BaseAddress feature isn't supported. + * + * @returns iprt status code. + * @retval VERR_LDR_FORWARDER forwarder, use pfnQueryForwarderInfo. Buffer size + * in @a pValue. + * @param pMod Pointer to the loader module structure. + * @param pvBits Pointer to bits returned by RTLDROPS::pfnGetBits(), optional. + * @param BaseAddress The image base address to use when calculating the symbol value. + * @param iOrdinal Symbol table ordinal, UINT32_MAX if the symbol name + * should be used. + * @param pszSymbol The symbol name. + * @param pValue Where to store the symbol value. + * @remark Extended loader feature. + */ + DECLCALLBACKMEMBER(int, pfnGetSymbolEx,(PRTLDRMODINTERNAL pMod, const void *pvBits, RTUINTPTR BaseAddress, + uint32_t iOrdinal, const char *pszSymbol, RTUINTPTR *pValue)); + + /** + * Query forwarder information on the specified symbol. + * + * This is an optional entrypoint. + * + * @returns iprt status code. + * @param pMod Pointer to the loader module structure. + * @param pvBits Pointer to bits returned by RTLDROPS::pfnGetBits(), + * optional. + * @param iOrdinal Symbol table ordinal of the forwarded symbol to query. + * UINT32_MAX if the symbol name should be used. + * @param pszSymbol The symbol name of the forwarded symbol to query. + * @param pInfo Where to return the forwarder information. + * @param cbInfo The size of the pInfo buffer. The pfnGetSymbolEx + * entrypoint returns the required size in @a pValue when + * the return code is VERR_LDR_FORWARDER. + * @remark Extended loader feature. + */ + DECLCALLBACKMEMBER(int, pfnQueryForwarderInfo,(PRTLDRMODINTERNAL pMod, const void *pvBits, uint32_t iOrdinal, + const char *pszSymbol, PRTLDRIMPORTINFO pInfo, size_t cbInfo)); + + /** + * Enumerates the debug info contained in the module. + * + * @returns iprt status code, which might have been returned by pfnCallback. + * @param pMod Pointer to the loader module structure. + * @param pvBits Pointer to the bits returned by RTLDROPS::pfnGetBits(), optional. + * @param pfnCallback The callback function which each debug info part is + * to be fed to. + * @param pvUser User argument to pass to the enumerator. + * @remark This is an optional entry point that can be NULL. + */ + DECLCALLBACKMEMBER(int, pfnEnumDbgInfo,(PRTLDRMODINTERNAL pMod, const void *pvBits, + PFNRTLDRENUMDBG pfnCallback, void *pvUser)); + + /** + * Enumerates the segments in the module. + * + * @returns iprt status code, which might have been returned by pfnCallback. + * @param pMod Pointer to the loader module structure. + * @param pfnCallback The callback function which each debug info part is + * to be fed to. + * @param pvUser User argument to pass to the enumerator. + * @remark This is an optional entry point that can be NULL. + */ + DECLCALLBACKMEMBER(int, pfnEnumSegments,(PRTLDRMODINTERNAL pMod, PFNRTLDRENUMSEGS pfnCallback, void *pvUser)); + + /** + * Converts a link address to a segment:offset address. + * + * @returns IPRT status code. + * + * @param pMod Pointer to the loader module structure. + * @param LinkAddress The link address to convert. + * @param piSeg Where to return the segment index. + * @param poffSeg Where to return the segment offset. + * @remark This is an optional entry point that can be NULL. + */ + DECLCALLBACKMEMBER(int, pfnLinkAddressToSegOffset,(PRTLDRMODINTERNAL pMod, RTLDRADDR LinkAddress, + uint32_t *piSeg, PRTLDRADDR poffSeg)); + + /** + * Converts a link address to a RVA. + * + * @returns IPRT status code. + * + * @param pMod Pointer to the loader module structure. + * @param LinkAddress The link address to convert. + * @param pRva Where to return the RVA. + * @remark This is an optional entry point that can be NULL. + */ + DECLCALLBACKMEMBER(int, pfnLinkAddressToRva,(PRTLDRMODINTERNAL pMod, RTLDRADDR LinkAddress, PRTLDRADDR pRva)); + + /** + * Converts a segment:offset to a RVA. + * + * @returns IPRT status code. + * + * @param pMod Pointer to the loader module structure. + * @param iSeg The segment index. + * @param offSeg The segment offset. + * @param pRva Where to return the RVA. + * @remark This is an optional entry point that can be NULL. + */ + DECLCALLBACKMEMBER(int, pfnSegOffsetToRva,(PRTLDRMODINTERNAL pMod, uint32_t iSeg, RTLDRADDR offSeg, PRTLDRADDR pRva)); + + /** + * Converts a RVA to a segment:offset. + * + * @returns IPRT status code. + * + * @param pMod Pointer to the loader module structure. + * @param Rva The RVA to convert. + * @param piSeg Where to return the segment index. + * @param poffSeg Where to return the segment offset. + * @remark This is an optional entry point that can be NULL. + */ + DECLCALLBACKMEMBER(int, pfnRvaToSegOffset,(PRTLDRMODINTERNAL pMod, RTLDRADDR Rva, uint32_t *piSeg, PRTLDRADDR poffSeg)); + + /** + * Reads a debug info part (section) from the image. + * + * This is primarily needed for getting DWARF sections in ELF image with fixups + * applied and won't be required by most other loader backends. + * + * @returns IPRT status code. + * + * @param pMod Pointer to the loader module structure. + * @param pvBuf The buffer to read into. + * @param iDbgInfo The debug info ordinal number if the request + * corresponds exactly to a debug info part from + * pfnEnumDbgInfo. Otherwise, pass UINT32_MAX. + * @param off The offset into the image file. + * @param cb The number of bytes to read. + */ + DECLCALLBACKMEMBER(int, pfnReadDbgInfo,(PRTLDRMODINTERNAL pMod, uint32_t iDbgInfo, RTFOFF off, size_t cb, void *pvBuf)); + + /** + * Generic method for querying image properties. + * + * @returns IPRT status code. + * @retval VERR_NOT_SUPPORTED if the property query isn't supported (either all + * or that specific property). + * @retval VERR_NOT_FOUND the property was not found in the module. + * + * @param pMod Pointer to the loader module structure. + * @param enmProp The property to query (valid). + * @param pvBits Pointer to the bits returned by + * RTLDROPS::pfnGetBits(), optional. + * @param pvBuf Pointer to the input / output buffer. This is valid. + * Normally only used for returning data, but in some + * cases it also holds input. + * @param cbBuf The size of the buffer (valid as per + * property). + * @param pcbRet The number of bytes actually returned. If + * VERR_BUFFER_OVERFLOW is returned, this is set to the + * required buffer size. + */ + DECLCALLBACKMEMBER(int, pfnQueryProp,(PRTLDRMODINTERNAL pMod, RTLDRPROP enmProp, void const *pvBits, + void *pvBuf, size_t cbBuf, size_t *pcbRet)); + + /** + * Verify the image signature. + * + * This may permform additional integrity checks on the image structures that + * was not done when opening the image. + * + * @returns IPRT status code. + * @retval VERR_LDRVI_NOT_SIGNED if not signed. + * + * @param pMod Pointer to the loader module structure. + * @param pfnCallback Callback that does the signature and certificate + * verification. + * @param pvUser User argument for the callback. + * @param pErrInfo Pointer to an error info buffer. Optional. + */ + DECLCALLBACKMEMBER(int, pfnVerifySignature,(PRTLDRMODINTERNAL pMod, PFNRTLDRVALIDATESIGNEDDATA pfnCallback, void *pvUser, + PRTERRINFO pErrInfo)); + + /** + * Calculate the image hash according the image signing rules. + * + * @returns IPRT status code. + * @param pMod The module handle. + * @param enmDigest Which kind of digest. + * @param pabHash Where to store the image hash. + * @param cbHash Size of the buffer @a pabHash points at. This has + * been validated to be at least the required size. + */ + DECLCALLBACKMEMBER(int, pfnHashImage,(PRTLDRMODINTERNAL pMod, RTDIGESTTYPE enmDigest, uint8_t *pabHash, size_t cbHash)); + + /** + * Try use unwind information to unwind one frame. + * + * @returns IPRT status code. Last informational status from stack reader callback. + * @retval VERR_DBG_NO_UNWIND_INFO if the module contains no unwind information. + * @retval VERR_DBG_UNWIND_INFO_NOT_FOUND if no unwind information was found + * for the location given by iSeg:off. + * + * @param pMod Pointer to the module structure. + * @param pvBits Pointer to the bits returned by + * RTLDROPS::pfnGetBits(), optional. + * @param iSeg The segment number of the program counter. UINT32_MAX for RVA. + * @param off The offset into @a iSeg. Together with @a iSeg + * this corresponds to the RTDBGUNWINDSTATE::uPc + * value pointed to by @a pState. + * @param pState The unwind state to work. + * + * @sa RTLdrUnwindFrame, RTDbgModUnwindFrame + */ + DECLCALLBACKMEMBER(int, pfnUnwindFrame,(PRTLDRMODINTERNAL pMod, void const *pvBits, uint32_t iSeg, RTUINTPTR off, + PRTDBGUNWINDSTATE pState)); + + /** Dummy entry to make sure we've initialized it all. */ + RTUINT uDummy; +} RTLDROPS; +typedef RTLDROPS *PRTLDROPS; +typedef const RTLDROPS *PCRTLDROPS; + + +/** + * Loader module core. + */ +typedef struct RTLDRMODINTERNAL +{ + /** The loader magic value (RTLDRMOD_MAGIC). */ + uint32_t u32Magic; + /** State. */ + RTLDRSTATE eState; + /** Loader ops. */ + PCRTLDROPS pOps; + /** Pointer to the reader instance. This is NULL for native image. */ + PRTLDRREADER pReader; + /** Image format. */ + RTLDRFMT enmFormat; + /** Image type. */ + RTLDRTYPE enmType; + /** Image endianness. */ + RTLDRENDIAN enmEndian; + /** Image target architecture. */ + RTLDRARCH enmArch; +} RTLDRMODINTERNAL; + + +/** + * Validates that a loader module handle is valid. + * + * @returns true if valid. + * @returns false if invalid. + * @param hLdrMod The loader module handle. + */ +DECLINLINE(bool) rtldrIsValid(RTLDRMOD hLdrMod) +{ + return RT_VALID_PTR(hLdrMod) + && ((PRTLDRMODINTERNAL)hLdrMod)->u32Magic == RTLDRMOD_MAGIC; +} + + +/** + * Native loader module. + */ +typedef struct RTLDRMODNATIVE +{ + /** The core structure. */ + RTLDRMODINTERNAL Core; + /** The native handle. */ + uintptr_t hNative; + /** The load flags (RTLDRLOAD_FLAGS_XXX). */ + uint32_t fFlags; +} RTLDRMODNATIVE; +/** Pointer to a native module. */ +typedef RTLDRMODNATIVE *PRTLDRMODNATIVE; + +/** @copydoc RTLDROPS::pfnGetSymbol */ +DECLCALLBACK(int) rtldrNativeGetSymbol(PRTLDRMODINTERNAL pMod, const char *pszSymbol, void **ppvValue); +/** @copydoc RTLDROPS::pfnClose */ +DECLCALLBACK(int) rtldrNativeClose(PRTLDRMODINTERNAL pMod); + +/** + * Load a native module using the native loader. + * + * @returns iprt status code. + * @param pszFilename The image filename. + * @param phHandle Where to store the module handle on success. + * @param fFlags RTLDRLOAD_FLAGS_XXX. + * @param pErrInfo Where to return extended error information. Optional. + */ +DECLHIDDEN(int) rtldrNativeLoad(const char *pszFilename, uintptr_t *phHandle, uint32_t fFlags, PRTERRINFO pErrInfo); + +/** + * Load a system library. + * + * @returns iprt status code. + * @param pszFilename The image filename. + * @param pszExt Extension to add. NULL if none. + * @param fFlags RTLDRLOAD_FLAGS_XXX. + * @param phLdrMod Where to return the module handle on success. + */ +DECLHIDDEN(int) rtldrNativeLoadSystem(const char *pszFilename, const char *pszExt, uint32_t fFlags, PRTLDRMOD phLdrMod); + +DECLHIDDEN(int) rtldrPEOpen(PRTLDRREADER pReader, uint32_t fFlags, RTLDRARCH enmArch, RTFOFF offNtHdrs, PRTLDRMOD phLdrMod, PRTERRINFO pErrInfo); +DECLHIDDEN(int) rtldrELFOpen(PRTLDRREADER pReader, uint32_t fFlags, RTLDRARCH enmArch, PRTLDRMOD phLdrMod, PRTERRINFO pErrInfo); +DECLHIDDEN(int) rtldrLXOpen(PRTLDRREADER pReader, uint32_t fFlags, RTLDRARCH enmArch, RTFOFF offLxHdr, PRTLDRMOD phLdrMod, PRTERRINFO pErrInfo); +DECLHIDDEN(int) rtldrMachOOpen(PRTLDRREADER pReader, uint32_t fFlags, RTLDRARCH enmArch, RTFOFF offImage, PRTLDRMOD phLdrMod, PRTERRINFO pErrInfo); +DECLHIDDEN(int) rtldrFatOpen(PRTLDRREADER pReader, uint32_t fFlags, RTLDRARCH enmArch, PRTLDRMOD phLdrMod, PRTERRINFO pErrInfo); +DECLHIDDEN(int) rtldrkLdrOpen(PRTLDRREADER pReader, uint32_t fFlags, RTLDRARCH enmArch, PRTLDRMOD phLdrMod, PRTERRINFO pErrInfo); + + +DECLHIDDEN(int) rtLdrReadAt(RTLDRMOD hLdrMod, void *pvBuf, uint32_t iDbgInfo, RTFOFF off, size_t cb); + +RT_C_DECLS_END + +#endif /* !IPRT_INCLUDED_INTERNAL_ldr_h */ + diff --git a/src/VBox/Runtime/include/internal/lockvalidator.h b/src/VBox/Runtime/include/internal/lockvalidator.h new file mode 100644 index 00000000..ff9e3d57 --- /dev/null +++ b/src/VBox/Runtime/include/internal/lockvalidator.h @@ -0,0 +1,129 @@ +/* $Id: lockvalidator.h $ */ +/** @file + * IPRT - Internal RTLockValidator header. + */ + +/* + * Copyright (C) 2006-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_INTERNAL_lockvalidator_h +#define IPRT_INCLUDED_INTERNAL_lockvalidator_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/types.h> +#include <iprt/lockvalidator.h> + +RT_C_DECLS_BEGIN + + +/** + * Record used only on the lock stack for recording the stack and source + * position of a recursive lock acquisition. + */ +typedef struct RTLOCKVALRECNEST +{ + RTLOCKVALRECCORE Core; + /** The recursion level at this point in the stack. */ + uint32_t cRecursion; + /** Pointer to the next record on the stack. */ + PRTLOCKVALRECUNION volatile pDown; + /** Pointer to the first recursion. */ + PRTLOCKVALRECUNION volatile pRec; + /** Pointer to the next free record when in the + * RTLOCKVALPERTHREAD::pFreeNestRecs list. */ + struct RTLOCKVALRECNEST *pNextFree; + /** The source position. */ + RTLOCKVALSRCPOS SrcPos; +} RTLOCKVALRECNEST; +/** Pointer to a recursion record. */ +typedef RTLOCKVALRECNEST *PRTLOCKVALRECNEST; + + +/** + * Record union for simplifying internal processing. + */ +typedef union RTLOCKVALRECUNION +{ + RTLOCKVALRECCORE Core; + RTLOCKVALRECEXCL Excl; + RTLOCKVALRECSHRD Shared; + RTLOCKVALRECSHRDOWN ShrdOwner; + RTLOCKVALRECNEST Nest; +} RTLOCKVALRECUNION; + + +/** + * Per thread data for the lock validator. + * + * This is part of the RTTHREADINT structure. + */ +typedef struct RTLOCKVALPERTHREAD +{ + /** Where we are blocking. */ + RTLOCKVALSRCPOS SrcPos; + /** Top of the lock stack. */ + PRTLOCKVALRECUNION volatile pStackTop; + /** List of free recursion (nesting) record. */ + PRTLOCKVALRECNEST pFreeNestRecs; + /** What we're blocking on. + * The lock validator sets this, RTThreadUnblock clears it. */ + PRTLOCKVALRECUNION volatile pRec; + /** The state in which pRec that goes with pRec. + * RTThreadUnblocking uses this to figure out when to clear pRec. */ + RTTHREADSTATE volatile enmRecState; + /** The thread is running inside the lock validator. */ + bool volatile fInValidator; + /** Reserved for alignment purposes. */ + bool afReserved[3]; + /** Number of registered write locks, mutexes and critsects that this thread owns. */ + int32_t volatile cWriteLocks; + /** Number of registered read locks that this thread owns, nesting included. */ + int32_t volatile cReadLocks; + /** Bitmap indicating which entires are free (set) and allocated (clear). */ + uint32_t volatile bmFreeShrdOwners; + /** Reserved for alignment purposes. */ + uint32_t u32Reserved; + /** Statically allocated shared owner records */ + RTLOCKVALRECSHRDOWN aShrdOwners[32]; +} RTLOCKVALPERTHREAD; + + +DECLHIDDEN(void) rtLockValidatorInitPerThread(RTLOCKVALPERTHREAD *pPerThread); +DECLHIDDEN(void) rtLockValidatorDeletePerThread(RTLOCKVALPERTHREAD *pPerThread); +DECLHIDDEN(void) rtLockValidatorSerializeDestructEnter(void); +DECLHIDDEN(void) rtLockValidatorSerializeDestructLeave(void); + +RT_C_DECLS_END + +#endif /* !IPRT_INCLUDED_INTERNAL_lockvalidator_h */ + diff --git a/src/VBox/Runtime/include/internal/magics.h b/src/VBox/Runtime/include/internal/magics.h new file mode 100644 index 00000000..7321c673 --- /dev/null +++ b/src/VBox/Runtime/include/internal/magics.h @@ -0,0 +1,296 @@ +/* $Id: magics.h $ */ +/** @file + * IPRT - Internal header defining The Magic Numbers. + */ + +/* + * Copyright (C) 2007-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_INTERNAL_magics_h +#define IPRT_INCLUDED_INTERNAL_magics_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +/** @name Magic Numbers. + * @{ */ + +/** Magic number for RTAIOMGRINT::u32Magic. (Emil Erich Kaestner) */ +#define RTAIOMGR_MAGIC UINT32_C(0x18990223) +/** Magic number for RTAIOMGRINTFILE::u32Magic. (Ephraim Kishon) */ +#define RTAIOMGRFILE_MAGIC UINT32_C(0x19240823) +/** Magic number for RTCRCIPHERINT::u32Magic. (Michael Wolff) */ +#define RTCRCIPHERINT_MAGIC UINT32_C(0x19530827) +/** Magic value for RTCRKEYINT::u32Magic. (Ronald Linn Rivest) */ +#define RTCRKEYINT_MAGIC UINT32_C(0x19470506) +/** Magic value for RTCRSSLINT::u32Magic. (Robert Upshur Woodward) */ +#define RTCRSSLINT_MAGIC UINT32_C(0x19430326) +/** Magic value for RTCRSSLSESSIONINT::u32Magic. (Carl Berstein) */ +#define RTCRSSLSESSIONINT_MAGIC UINT32_C(0x19440214) +/** Magic number for RTDBGMODINT::u32Magic. (Charles Lloyd) */ +#define RTDBGAS_MAGIC UINT32_C(0x19380315) +/** Magic number for RTDBGCFGINT::u32Magic. (McCoy Tyner) */ +#define RTDBGCFG_MAGIC UINT32_C(0x19381211) +/** Magic number for RTDBGMODINT::u32Magic. (Keith Jarrett) */ +#define RTDBGMOD_MAGIC UINT32_C(0x19450508) +/** Magic number for RTDBGMODDEFERRED::u32Magic. (Chet Baker) */ +#define RTDBGMODDEFERRED_MAGIC UINT32_C(0x19291223) +/** Magic number for RTDBGMODDEFERRED::u32Magic after release. */ +#define RTDBGMODDEFERRED_MAGIC_DEAD UINT32_C(0x19880513) +/** Magic number for RTDBGMODLDR::u32Magic. (Gerry Mulligan) */ +#define RTDBGMODLDR_MAGIC UINT32_C(0x19270406) +/** Magic number for RTDBGMODLDR::u32Magic after close. */ +#define RTDBGMODLDR_MAGIC_DEAD UINT32_C(0x19960120) +/** Magic number for RTDBGMODVTIMG::u32Magic. (Jack DeJohnette) */ +#define RTDBGMODVTDBG_MAGIC UINT32_C(0x19420809) +/** Magic number for RTDBGMODVTIMG::u32Magic. (Cecil McBee) */ +#define RTDBGMODVTIMG_MAGIC UINT32_C(0x19350419) +/** Magic value for RTDBGKRNLINFOINT::u32Magic. (John Carmack) */ +#define RTDBGKRNLINFO_MAGIC UINT32_C(0x19700820) +/** The value of RTDIRINTERNAL::u32Magic. (Michael Ende) */ +#define RTDIR_MAGIC UINT32_C(0x19291112) +/** The value of RTDIRINTERNAL::u32Magic after RTDirClose(). */ +#define RTDIR_MAGIC_DEAD UINT32_C(0x19950829) +/** The value of RTDVMINTERNAL::u32Magic. (Dan Brown) */ +#define RTDVM_MAGIC UINT32_C(0x19640622) +/** The value of RTDVMINTERNAL::u32Magic after close. */ +#define RTDVM_MAGIC_DEAD (~RTDVM_MAGIC) +/** The value of RTDVMVOLUMEINTERNAL::u32Magic. (Daniel Defoe) */ +#define RTDVMVOLUME_MAGIC UINT32_C(0x16591961) +/** The value of RTDVMVOLUMEINTERNAL::u32Magic after close. */ +#define RTDVMVOLUME_MAGIC_DEAD UINT32_C(0x17310424) +/** The value of RTFILEAIOCTXINT::u32Magic. (Howard Phillips Lovecraft) */ +#define RTFILEAIOCTX_MAGIC UINT32_C(0x18900820) +/** The value of RTFILEAIOCTXINT::u32Magic after RTFileAioCtxDestroy(). */ +#define RTFILEAIOCTX_MAGIC_DEAD UINT32_C(0x19370315) +/** The value of RTFILEAIOREQINT::u32Magic. (Stephen Edwin King) */ +#define RTFILEAIOREQ_MAGIC UINT32_C(0x19470921) +/** The magic value for RTFTPSERVERINTERNAL::u32Magic. */ +#define RTFTPSERVER_MAGIC UINT32_C(0x20170610) +/** The value of RTFTPSERVERINTERNAL::u32Magic after close. */ +#define RTFTPSERVER_MAGIC_DEAD (~RTFTPSERVER_MAGIC) +/** The magic value for RTFTPSERVERINTERNAL::u32Magic. */ +#define RTHTTPSERVER_MAGIC UINT32_C(0x20200602) +/** The value for RTFTPSERVERINTERNAL::u32Magic after close. */ +#define RTHTTPSERVER_MAGIC_DEAD (~RTHTTPSERVER_MAGIC) +/** The value of RTENVINTERNAL::u32Magic. (Rumiko Takahashi) */ +#define RTENV_MAGIC UINT32_C(0x19571010) +/** The value of RTERRVARS::ai32Vars[0]. (Ryuichi Sakamoto) */ +#define RTERRVARS_MAGIC UINT32_C(0x19520117) +/** The value of RTFSISOMAKERINT::uMagic. (Brian Blade) */ +#define RTFSISOMAKERINT_MAGIC UINT32_C(0x19700725) +/** Magic number for RTHANDLETABLEINT::u32Magic. (Hitomi Kanehara) */ +#define RTHANDLETABLE_MAGIC UINT32_C(0x19830808) +/** Magic number for RTHEAPOFFSETINTERNAL::u32Magic. (Neal Town Stephenson) */ +#define RTHEAPOFFSET_MAGIC UINT32_C(0x19591031) +/** Magic number for RTHEAPSIMPLEINTERNAL::uMagic. (Kyoichi Katayama) */ +#define RTHEAPSIMPLE_MAGIC UINT32_C(0x19590105) +/** The magic value for RTHTTPINTERNAL::u32Magic. (Karl May) */ +#define RTHTTP_MAGIC UINT32_C(0x18420225) +/** The value of RTHTTPINTERNAL::u32Magic after close. */ +#define RTHTTP_MAGIC_DEAD UINT32_C(0x19120330) +/** The magic value for RTHTTPHEADERLISTINTERNAL::u32Magic. (Ken Follett) */ +#define RTHTTPHEADERLIST_MAGIC UINT32_C(0x19490605) +/** The value of RTHTTPHEADERLISTINTERNAL::u32Magic after close. */ +#define RTHTTPHEADERLIST_MAGIC_DEAD (~RTHTTPHEADERLIST_MAGIC) +/** The value of RTINIFILEINT::u32Magic. (Jane Austen) */ +#define RTINIFILE_MAGIC UINT32_C(0x17751216) +/** The value of RTINIFILEINT::u32Magic after close. */ +#define RTINIFILE_MAGIC_DEAD UINT32_C(0x18170718) +/** The magic value for RTLDRMODINTERNAL::u32Magic. (Alan Moore) */ +#define RTLDRMOD_MAGIC UINT32_C(0x19531118) +/** The magic value for RTLOCALIPCSERVER::u32Magic. (Naoki Yamamoto) */ +#define RTLOCALIPCSERVER_MAGIC UINT32_C(0x19600201) +/** The magic value for RTLOCALIPCSERVER::u32Magic. (Katsuhiro Otomo) */ +#define RTLOCALIPCSESSION_MAGIC UINT32_C(0x19530414) +/** The magic value for RTLOCKVALCLASSINT::u32Magic. (Thomas Mann) */ +#define RTLOCKVALCLASS_MAGIC UINT32_C(0x18750605) +/** The magic value for RTLOCKVALCLASSINT::u32Magic after destruction. */ +#define RTLOCKVALCLASS_MAGIC_DEAD UINT32_C(0x19550812) +/** The magic value for RTLOCKVALRECEXCL::u32Magic. (Vladimir Vladimirovich Nabokov) */ +#define RTLOCKVALRECEXCL_MAGIC UINT32_C(0x18990422) +/** The dead magic value for RTLOCKVALRECEXCL::u32Magic. */ +#define RTLOCKVALRECEXCL_MAGIC_DEAD UINT32_C(0x19770702) +/** The magic value for RTLOCKVALRECSHRD::u32Magic. (Agnar Mykle) */ +#define RTLOCKVALRECSHRD_MAGIC UINT32_C(0x19150808) +/** The magic value for RTLOCKVALRECSHRD::u32Magic after deletion. */ +#define RTLOCKVALRECSHRD_MAGIC_DEAD UINT32_C(0x19940115) +/** The magic value for RTLOCKVALRECSHRDOWN::u32Magic. (Jens Ingvald Bjoerneboe) */ +#define RTLOCKVALRECSHRDOWN_MAGIC UINT32_C(0x19201009) +/** The magic value for RTLOCKVALRECSHRDOWN::u32Magic after deletion. */ +#define RTLOCKVALRECSHRDOWN_MAGIC_DEAD UINT32_C(0x19760509) +/** The magic value for RTLOCKVALRECNEST::u32Magic. (Anne Desclos) */ +#define RTLOCKVALRECNEST_MAGIC UINT32_C(0x19071123) +/** The magic value for RTLOCKVALRECNEST::u32Magic after deletion. */ +#define RTLOCKVALRECNEST_MAGIC_DEAD UINT32_C(0x19980427) +/** Magic number for RTMEMCACHEINT::u32Magic. (Joseph Weizenbaum) */ +#define RTMEMCACHE_MAGIC UINT32_C(0x19230108) +/** Dead magic number for RTMEMCACHEINT::u32Magic. */ +#define RTMEMCACHE_MAGIC_DEAD UINT32_C(0x20080305) +/** The magic value for RTMEMPOOL::u32Magic. (Jane Austin) */ +#define RTMEMPOOL_MAGIC UINT32_C(0x17751216) +/** The magic value for RTMEMPOOL::u32Magic after RTMemPoolDestroy. */ +#define RTMEMPOOL_MAGIC_DEAD UINT32_C(0x18170718) +/** The magic value for heap blocks. (Edgar Allan Poe) */ +#define RTMEMHDR_MAGIC UINT32_C(0x18090119) +/** The magic value for heap blocks after freeing. */ +#define RTMEMHDR_MAGIC_DEAD UINT32_C(0x18491007) +/** The value of RTPIPEINTERNAL::u32Magic. (Frank Schaetzing) */ +#define RTPIPE_MAGIC UINT32_C(0x19570528) +/** The value of RTPOLLSETINTERNAL::u32Magic. (Ai Yazawa) */ +#define RTPOLLSET_MAGIC UINT32_C(0x19670307) +/** RTR0MEMOBJ::u32Magic. (Masakazu Katsura) */ +#define RTR0MEMOBJ_MAGIC UINT32_C(0x19611210) +/** RTRANDINT::u32Magic. (Alan Moore) */ +#define RTRANDINT_MAGIC UINT32_C(0x19531118) +/** The value of RTREQ::u32Magic. */ +#define RTREQ_MAGIC UINT32_C(0xfeed0001) /**< @todo find a value */ +/** The value of RTREQ::u32Magic of a freed request. */ +#define RTREQ_MAGIC_DEAD (~RTREQ_MAGIC) +/** The value of RTREQPOOLINT::u32Magic. */ +#define RTREQPOOL_MAGIC UINT32_C(0xfeed0002)/**< @todo find a value */ +/** The value of RTREQPOOLINT::u32Magic after destruction. */ +#define RTREQPOOL_MAGIC_DEAD (~RTREQPOOL_MAGIC) +/** The value of RTREQQUEUEINT::u32Magic. */ +#define RTREQQUEUE_MAGIC UINT32_C(0xfeed0003)/**< @todo find a value */ +/** The value of RTREQQUEUEINT::u32Magic after destruction. */ +#define RTREQQUEUE_MAGIC_DEAD (~RTREQQUEUE_MAGIC) +/** The value of RTS3::u32Magic. (Edgar Wallace) */ +#define RTS3_MAGIC UINT32_C(0x18750401) +/** The value of RTS3::u32Magic after RTS3Destroy(). */ +#define RTS3_MAGIC_DEAD UINT32_C(0x19320210) +/** Magic for the event semaphore structure. (Neil Gaiman) */ +#define RTSEMEVENT_MAGIC UINT32_C(0x19601110) +/** Magic for the multiple release event semaphore structure. (Isaac Asimov) */ +#define RTSEMEVENTMULTI_MAGIC UINT32_C(0x19200102) +/** Dead magic value for multiple release event semaphore structures. */ +#define RTSEMEVENTMULTI_MAGIC_DEAD UINT32_C(0x19920406) +/** Magic value for RTSEMFASTMUTEXINTERNAL::u32Magic. (John Ronald Reuel Tolkien) */ +#define RTSEMFASTMUTEX_MAGIC UINT32_C(0x18920103) +/** Dead magic value for RTSEMFASTMUTEXINTERNAL::u32Magic. */ +#define RTSEMFASTMUTEX_MAGIC_DEAD UINT32_C(0x19730902) +/** Magic for the mutex semaphore structure. (Douglas Adams) */ +#define RTSEMMUTEX_MAGIC UINT32_C(0x19520311) +/** Dead magic for the mutex semaphore structure. */ +#define RTSEMMUTEX_MAGIC_DEAD UINT32_C(0x20010511) +/** Magic for the spinning mutex semaphore structure. (Natsume Soseki) */ +#define RTSEMSPINMUTEX_MAGIC UINT32_C(0x18670209) +/** Dead magic value for RTSEMSPINMUTEXINTERNAL::u32Magic. */ +#define RTSEMSPINMUTEX_MAGIC_DEAD UINT32_C(0x19161209) +/** RTSEMRWINTERNAL::u32Magic value. (Kosuke Fujishima) */ +#define RTSEMRW_MAGIC UINT32_C(0x19640707) +/** RTSEMXROADSINTERNAL::u32Magic value. (Kenneth Elton "Ken" Kesey) */ +#define RTSEMXROADS_MAGIC UINT32_C(0x19350917) +/** RTSEMXROADSINTERNAL::u32Magic value after RTSemXRoadsDestroy. */ +#define RTSEMXROADS_MAGIC_DEAD UINT32_C(0x20011110) +/** RTSERIALPORTINTERNAL::u32Magic value (Jules-Gabriel Verne). */ +#define RTSERIALPORT_MAGIC UINT32_C(0x18280208) +/** RTSERIALPORTINTERNAL::u32Magic value after RTSerialPortClose. */ +#define RTSERIALPORT_MAGIC_DEAD UINT32_C(0x19050324) +/** RTSHMEMINT::u32Magic value (Stephen William Hawking) */ +#define RTSHMEM_MAGIC UINT32_C(0x19420108) +/** RTSHMEMINT::u32Magic value after RTShMemClose */ +#define RTSHMEM_MAGIC_DEAD UINT32_C(0x20180314) +/** The magic value for RTSOCKETINT::u32Magic. (Stanislaw Lem) */ +#define RTSOCKET_MAGIC UINT32_C(0x19210912) +/** The magic value for RTSOCKETINT::u32Magic after destruction. */ +#define RTSOCKET_MAGIC_DEAD UINT32_C(0x20060326) +/** Magic value for RTSPINLOCKINTERNAL::u32Magic. (Terry Pratchett) */ +#define RTSPINLOCK_MAGIC UINT32_C(0x19480428) +/** Magic value for generic RTSPINLOCKINTERNAL::u32Magic (Georges Prosper Remi). */ +#define RTSPINLOCK_GEN_MAGIC UINT32_C(0x10970522) +/** Magic value for RTSTRCACHE::u32Magic. (Sir Arthur Charles Clarke) */ +#define RTSTRCACHE_MAGIC UINT32_C(0x19171216) +/** Magic value for RTSTRCACHE::u32Magic after RTStrCacheDestroy. */ +#define RTSTRCACHE_MAGIC_DEAD UINT32_C(0x20080319) +/** The value of RTSTREAM::u32Magic for a valid stream. */ +#define RTSTREAM_MAGIC UINT32_C(0xe44e44ee) +/** Magic value for RTTCPSERVER::u32Magic. (Jan Garbarek) */ +#define RTTCPSERVER_MAGIC UINT32_C(0x19470304) +/** Magic value for RTTCPSERVER::u32Magic. (Harlan Ellison) */ +#define RTUDPSERVER_MAGIC UINT32_C(0x19340527) +/** RTTESTINT::u32Magic value. (Daniel Kehlmann) */ +#define RTTESTINT_MAGIC UINT32_C(0x19750113) +/** RTTHREADCTXHOOKINT::u32Magic value. (Dennis MacAlistair Ritchie) */ +#define RTTHREADCTXHOOKINT_MAGIC UINT32_C(0x19410909) +/** RTTHREADINT::u32Magic value. (Gilbert Keith Chesterton) */ +#define RTTHREADINT_MAGIC UINT32_C(0x18740529) +/** RTTHREADINT::u32Magic value for a dead thread. */ +#define RTTHREADINT_MAGIC_DEAD UINT32_C(0x19360614) +/** Magic number for timer handles. (Jared Mason Diamond) */ +#define RTTIMER_MAGIC UINT32_C(0x19370910) +/** Magic number for timer low resolution handles. (Saki Hiwatari) */ +#define RTTIMERLR_MAGIC UINT32_C(0x19610715) +/** Magic value of RTTRACEBUFINT::u32Magic. (George Orwell) */ +#define RTTRACEBUF_MAGIC UINT32_C(0x19030625) +/** Magic value of RTTRACEBUFINT::u32Magic after the final release. */ +#define RTTRACEBUF_MAGIC_DEAD UINT32_C(0x19500121) +/** The value of RTTRACELOGRDRINT::u32Magic. (John Michael Scalzi) */ +#define RTTRACELOGRDR_MAGIC UINT32_C(0x19690510) +/** The value of RTTRACELOGRDRINT::u32Magic after RTTraceLogRdrDestroy(). */ +#define RTTRACELOGRDR_MAGIC_DEAD (~RTTRACELOGRDR_MAGIC) +/** The value of RTTRACELOGWRINT::u32Magic. (Herbert George Wells) */ +#define RTTRACELOGWR_MAGIC UINT32_C(0x18660921) +/** The value of RTTRACELOGWRINT::u32Magic after RTTraceLogWrDestroy(). */ +#define RTTRACELOGWR_MAGIC_DEAD UINT32_C(0x19460813) +/** The value of RTVFSOBJINTERNAL::u32Magic. (Yasunari Kawabata) */ +#define RTVFSOBJ_MAGIC UINT32_C(0x18990614) +/** The value of RTVFSOBJINTERNAL::u32Magic after close. */ +#define RTVFSOBJ_MAGIC_DEAD UINT32_C(0x19720416) +/** The value of RTVFSINTERNAL::u32Magic. (Sir Kingsley William Amis) */ +#define RTVFS_MAGIC UINT32_C(0x19220416) +/** The value of RTVFSINTERNAL::u32Magic after close. */ +#define RTVFS_MAGIC_DEAD UINT32_C(0x19951022) +/** The value of RTVFSFSSTREAMINTERNAL::u32Magic. (William McGuire "Bill" Bryson) */ +#define RTVFSFSSTREAM_MAGIC UINT32_C(0x19511208) +/** The value of RTVFSFSSTREAMINTERNAL::u32Magic after close */ +#define RTVFSFSSTREAM_MAGIC_DEAD (~RTVFSFSSTREAM_MAGIC) +/** The value of RTVFSDIRINTERNAL::u32Magic. (Franklin Patrick Herbert, Jr.) */ +#define RTVFSDIR_MAGIC UINT32_C(0x19201008) +/** The value of RTVFSDIRINTERNAL::u32Magic after close. */ +#define RTVFSDIR_MAGIC_DEAD UINT32_C(0x19860211) +/** The value of RTVFSFILEINTERNAL::u32Magic. (Charles John Huffam Dickens) */ +#define RTVFSFILE_MAGIC UINT32_C(0x18120207) +/** The value of RTVFSFILEINTERNAL::u32Magic after close. */ +#define RTVFSFILE_MAGIC_DEAD UINT32_C(0x18700609) +/** The value of RTVFSIOSTREAMINTERNAL::u32Magic. (Ernest Miller Hemingway) */ +#define RTVFSIOSTREAM_MAGIC UINT32_C(0x18990721) +/** The value of RTVFSIOSTREAMINTERNAL::u32Magic after close. */ +#define RTVFSIOSTREAM_MAGIC_DEAD UINT32_C(0x19610702) +/** The value of RTVFSSYMLINKINTERNAL::u32Magic. (Francis Scott Key Fitzgerald) */ +#define RTVFSSYMLINK_MAGIC UINT32_C(0x18960924) +/** The value of RTVFSSYMLINKINTERNAL::u32Magic after close. */ +#define RTVFSSYMLINK_MAGIC_DEAD UINT32_C(0x19401221) + +/** @} */ + +#endif /* !IPRT_INCLUDED_INTERNAL_magics_h */ + diff --git a/src/VBox/Runtime/include/internal/mem.h b/src/VBox/Runtime/include/internal/mem.h new file mode 100644 index 00000000..3831c2d5 --- /dev/null +++ b/src/VBox/Runtime/include/internal/mem.h @@ -0,0 +1,87 @@ +/* $Id: mem.h $ */ +/** @file + * IPRT - Memory Management. + */ + +/* + * Copyright (C) 2010-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_INTERNAL_mem_h +#define IPRT_INCLUDED_INTERNAL_mem_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/cdefs.h> + +RT_C_DECLS_BEGIN + +/** + * Special allocation method that does not have any IPRT dependencies. + * + * This is suitable for allocating memory for IPRT heaps, pools, caches, memory + * trackers, semaphores and similar that end up in bootstrap depencency hell + * otherwise. + * + * @returns Pointer to the allocated memory, NULL on failure. Must be freed by + * calling rtMemBaseFree(). + * @param cb The number of bytes to allocate. + */ +DECLHIDDEN(void *) rtMemBaseAlloc(size_t cb); + +/** + * Frees memory allocated by rtInitAlloc(). + * + * @param pv What rtInitAlloc() returned. + */ +DECLHIDDEN(void) rtMemBaseFree(void *pv); + + +#ifdef IN_RING0 +/** @def RTR0MEM_WITH_EF_APIS + * Enables the electrict fence APIs. + * + * Requires working rtR0MemObjNativeProtect implementation, thus the current + * OS restrictions. + */ +# if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD) || defined(DOXYGEN_RUNNING) +# define RTR0MEM_WITH_EF_APIS +# endif +# ifdef RTR0MEM_WITH_EF_APIS +DECLHIDDEN(void) rtR0MemEfInit(void); +DECLHIDDEN(void) rtR0MemEfTerm(void); +# endif +#endif + +RT_C_DECLS_END + +#endif /* !IPRT_INCLUDED_INTERNAL_mem_h */ + diff --git a/src/VBox/Runtime/include/internal/memobj.h b/src/VBox/Runtime/include/internal/memobj.h new file mode 100644 index 00000000..57c55862 --- /dev/null +++ b/src/VBox/Runtime/include/internal/memobj.h @@ -0,0 +1,547 @@ +/* $Id: memobj.h $ */ +/** @file + * IPRT - Ring-0 Memory Objects. + */ + +/* + * Copyright (C) 2006-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_INTERNAL_memobj_h +#define IPRT_INCLUDED_INTERNAL_memobj_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/memobj.h> +#include <iprt/assert.h> +#include "internal/magics.h" + +RT_C_DECLS_BEGIN + +/** @defgroup grp_rt_memobj_int Internals. + * @ingroup grp_rt_memobj + * @internal + * @{ + */ + +/** + * Ring-0 memory object type. + */ +typedef enum RTR0MEMOBJTYPE +{ + /** The traditional invalid value. */ + RTR0MEMOBJTYPE_INVALID = 0, + + /** @name Primary types (parents) + * @{ */ + /** RTR0MemObjAllocPage. + * This memory is page aligned and fixed. */ + RTR0MEMOBJTYPE_PAGE, + /** RTR0MemObjAllocLarge. */ + RTR0MEMOBJTYPE_LARGE_PAGE, + /** RTR0MemObjAllocLow. + * This memory is page aligned, fixed and is backed by physical memory below 4GB. */ + RTR0MEMOBJTYPE_LOW, + /** RTR0MemObjAllocCont. + * This memory is page aligned, fixed and is backed by contiguous physical memory below 4GB. */ + RTR0MEMOBJTYPE_CONT, + /** RTR0MemObjLockKernel, RTR0MemObjLockUser. + * This memory is page aligned and fixed. It was locked/pinned/wired down by the API call. */ + RTR0MEMOBJTYPE_LOCK, + /** RTR0MemObjAllocPhys, RTR0MemObjEnterPhys. + * This memory is physical memory, page aligned, contiguous and doesn't need to have a mapping. */ + RTR0MEMOBJTYPE_PHYS, + /** RTR0MemObjAllocPhysNC. + * This memory is physical memory, page aligned and doesn't need to have a mapping. */ + RTR0MEMOBJTYPE_PHYS_NC, + /** RTR0MemObjReserveKernel, RTR0MemObjReserveUser. + * This memory is page aligned and has no backing. */ + RTR0MEMOBJTYPE_RES_VIRT, + /** @} */ + + /** @name Secondary types (children) + * @{ + */ + /** RTR0MemObjMapUser, RTR0MemObjMapKernel. + * This is a user or kernel context mapping of another ring-0 memory object. */ + RTR0MEMOBJTYPE_MAPPING, + /** @} */ + + /** The end of the valid types. Used for sanity checking. */ + RTR0MEMOBJTYPE_END +} RTR0MEMOBJTYPE; + + +/** @name RTR0MEMOBJINTERNAL::fFlags + * @{ */ +/** Page level protection was changed. */ +#define RTR0MEMOBJ_FLAGS_PROT_CHANGED RT_BIT_32(0) +/** Zero initialized at allocation. */ +#define RTR0MEMOBJ_FLAGS_ZERO_AT_ALLOC RT_BIT_32(1) +/** Uninitialized at allocation. */ +#define RTR0MEMOBJ_FLAGS_UNINITIALIZED_AT_ALLOC RT_BIT_32(2) +/** @} */ + + +typedef struct RTR0MEMOBJINTERNAL *PRTR0MEMOBJINTERNAL; +typedef struct RTR0MEMOBJINTERNAL **PPRTR0MEMOBJINTERNAL; + +/** + * Ring-0 memory object. + * + * When using the PRTR0MEMOBJINTERNAL and PPRTR0MEMOBJINTERNAL types + * we get pMem and ppMem variable names. + * + * When using the RTR0MEMOBJ and PRTR0MEMOBJ types we get MemObj and + * pMemObj variable names. We never dereference variables of the RTR0MEMOBJ + * type, we always convert it to a PRTR0MEMOBJECTINTERNAL variable first. + */ +typedef struct RTR0MEMOBJINTERNAL +{ + /** Magic number (RTR0MEMOBJ_MAGIC). */ + uint32_t u32Magic; + /** The size of this structure. */ + uint32_t cbSelf; + /** The type of allocation. */ + RTR0MEMOBJTYPE enmType; + /** Flags, RTR0MEMOBJ_FLAGS_*. */ + uint32_t fFlags; + /** The size of the memory allocated, pinned down, or mapped. */ + size_t cb; + /** The memory address. + * What this really is varies with the type. + * For PAGE, CONT, LOW, RES_VIRT/R0, LOCK/R0 and MAP/R0 it's the ring-0 mapping. + * For LOCK/R3, RES_VIRT/R3 and MAP/R3 it is the ring-3 mapping. + * For PHYS this might actually be NULL if there isn't any mapping. + */ + void *pv; + + /** Object relations. */ + union + { + /** This is for tracking child memory handles mapping the + * memory described by the primary handle. */ + struct + { + /** Number of mappings. */ + uint32_t cMappingsAllocated; + /** Number of mappings in the array. */ + uint32_t cMappings; + /** Pointers to child handles mapping this memory. */ + PPRTR0MEMOBJINTERNAL papMappings; + } Parent; + + /** Pointer to the primary handle. */ + struct + { + /** Pointer to the parent. */ + PRTR0MEMOBJINTERNAL pParent; + } Child; + } uRel; + + /** Type specific data for the memory types that requires that. */ + union + { + /** RTR0MEMTYPE_PAGE. */ + struct + { + unsigned iDummy; + } Page; + + /** RTR0MEMTYPE_LOW. */ + struct + { + unsigned iDummy; + } Low; + + /** RTR0MEMTYPE_CONT. */ + struct + { + /** The physical address of the first page. */ + RTHCPHYS Phys; + } Cont; + + /** RTR0MEMTYPE_LOCK_USER. */ + struct + { + /** The process that owns the locked memory. + * This is NIL_RTR0PROCESS if it's kernel memory. */ + RTR0PROCESS R0Process; + } Lock; + + /** RTR0MEMTYPE_PHYS. */ + struct + { + /** The base address of the physical memory. */ + RTHCPHYS PhysBase; + /** If set this object was created by RTR0MemPhysAlloc, otherwise it was + * created by RTR0MemPhysEnter. */ + bool fAllocated; + /** See RTMEM_CACHE_POLICY_XXX constants */ + uint32_t uCachePolicy; + } Phys; + + /** RTR0MEMTYPE_PHYS_NC. */ + struct + { + unsigned iDummy; + } PhysNC; + + /** RTR0MEMOBJTYPE_RES_VIRT */ + struct + { + /** The process that owns the reserved memory. + * This is NIL_RTR0PROCESS if it's kernel memory. */ + RTR0PROCESS R0Process; + } ResVirt; + + /** RTR0MEMOBJTYPE_MAPPING */ + struct + { + /** The process that owns the reserved memory. + * This is NIL_RTR0PROCESS if it's kernel memory. */ + RTR0PROCESS R0Process; + } Mapping; + } u; + +#if defined(DEBUG) + /** Allocation tag string. */ + const char *pszTag; +#endif +} RTR0MEMOBJINTERNAL; + + +/** + * Checks if this is mapping or not. + * + * @returns true if it's a mapping, otherwise false. + * @param pMem The ring-0 memory object handle. + * @see RTR0MemObjIsMapping + */ +DECLINLINE(bool) rtR0MemObjIsMapping(PRTR0MEMOBJINTERNAL pMem) +{ + switch (pMem->enmType) + { + case RTR0MEMOBJTYPE_MAPPING: + return true; + + default: + return false; + } +} + + +/** + * Checks page level protection can be changed on this object. + * + * @returns true / false. + * @param pMem The ring-0 memory object handle. + */ +DECLINLINE(bool) rtR0MemObjIsProtectable(PRTR0MEMOBJINTERNAL pMem) +{ + switch (pMem->enmType) + { + case RTR0MEMOBJTYPE_MAPPING: + case RTR0MEMOBJTYPE_PAGE: + case RTR0MEMOBJTYPE_LOW: + case RTR0MEMOBJTYPE_CONT: + return true; + + default: + return false; + } +} + + +/** + * Checks if RTR0MEMOBJ::pv is a ring-3 pointer or not. + * + * @returns true if it's a object with a ring-3 address, otherwise false. + * @param pMem The ring-0 memory object handle. + */ +DECLINLINE(bool) rtR0MemObjIsRing3(PRTR0MEMOBJINTERNAL pMem) +{ + switch (pMem->enmType) + { + case RTR0MEMOBJTYPE_RES_VIRT: + return pMem->u.ResVirt.R0Process != NIL_RTR0PROCESS; + case RTR0MEMOBJTYPE_LOCK: + return pMem->u.Lock.R0Process != NIL_RTR0PROCESS; + case RTR0MEMOBJTYPE_MAPPING: + return pMem->u.Mapping.R0Process != NIL_RTR0PROCESS; + default: + return false; + } +} + + +/** + * Frees the memory object (but not the handle). + * Any OS specific handle resources will be freed by this call. + * + * @returns IPRT status code. On failure it is assumed that the object remains valid. + * @param pMem The ring-0 memory object handle to the memory which should be freed. + */ +DECLHIDDEN(int) rtR0MemObjNativeFree(PRTR0MEMOBJINTERNAL pMem); + +/** + * Allocates page aligned virtual kernel memory. + * + * The memory is taken from a non paged (= fixed physical memory backing) pool. + * + * @returns IPRT status code. + * @param ppMem Where to store the ring-0 memory object handle. + * @param cb Number of bytes to allocate, page aligned. + * @param fExecutable Flag indicating whether it should be permitted to executed code in the memory object. + * @param pszTag Allocation tag used for statistics and such. + */ +DECLHIDDEN(int) rtR0MemObjNativeAllocPage(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable, const char *pszTag); + +/** + * Worker for RTR0MemObjAllocLargeTag. + * + * @returns IPRT status code. + * @param ppMem Where to store the ring-0 memory object handle. + * @param cb Number of bytes to allocate, aligned to @a + * cbLargePage. + * @param cbLargePage The large page size. + * @param fFlags RTMEMOBJ_ALLOC_LARGE_F_XXX, validated. + * @param pszTag The allocation tag. + */ +DECLHIDDEN(int) rtR0MemObjNativeAllocLarge(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, size_t cbLargePage, uint32_t fFlags, + const char *pszTag); + +/** + * Allocates page aligned virtual kernel memory with physical backing below 4GB. + * + * The physical memory backing the allocation is fixed. + * + * @returns IPRT status code. + * @param ppMem Where to store the ring-0 memory object handle. + * @param cb Number of bytes to allocate, page aligned. + * @param fExecutable Flag indicating whether it should be permitted to executed code in the memory object. + * @param pszTag Allocation tag used for statistics and such. + */ +DECLHIDDEN(int) rtR0MemObjNativeAllocLow(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable, const char *pszTag); + +/** + * Allocates page aligned virtual kernel memory with contiguous physical backing below 4GB. + * + * The physical memory backing the allocation is fixed. + * + * @returns IPRT status code. + * @param ppMem Where to store the ring-0 memory object handle. + * @param cb Number of bytes to allocate, page aligned. + * @param fExecutable Flag indicating whether it should be permitted to executed code in the memory object. + * @param pszTag Allocation tag used for statistics and such. + */ +DECLHIDDEN(int) rtR0MemObjNativeAllocCont(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable, const char *pszTag); + +/** + * Locks a range of user virtual memory. + * + * @returns IPRT status code. + * @param ppMem Where to store the ring-0 memory object handle. + * @param R3Ptr User virtual address, page aligned. + * @param cb Number of bytes to lock, page aligned. + * @param fAccess The desired access, a combination of RTMEM_PROT_READ + * and RTMEM_PROT_WRITE. + * @param R0Process The process to lock pages in. + * @param pszTag Allocation tag used for statistics and such. + */ +DECLHIDDEN(int) rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3Ptr, size_t cb, uint32_t fAccess, + RTR0PROCESS R0Process, const char *pszTag); + +/** + * Locks a range of kernel virtual memory. + * + * @returns IPRT status code. + * @param ppMem Where to store the ring-0 memory object handle. + * @param pv Kernel virtual address, page aligned. + * @param cb Number of bytes to lock, page aligned. + * @param fAccess The desired access, a combination of RTMEM_PROT_READ + * and RTMEM_PROT_WRITE. + * @param pszTag Allocation tag used for statistics and such. + */ +DECLHIDDEN(int) rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb, uint32_t fAccess, const char *pszTag); + +/** + * Allocates contiguous page aligned physical memory without (necessarily) any + * kernel mapping. + * + * @returns IPRT status code. + * @param ppMem Where to store the ring-0 memory object handle. + * @param cb Number of bytes to allocate, page aligned. + * @param PhysHighest The highest permitable address (inclusive). + * NIL_RTHCPHYS if any address is acceptable. + * @param uAlignment The alignment of the reserved memory. + * Supported values are PAGE_SIZE, _2M, _4M and _1G. + * @param pszTag Allocation tag used for statistics and such. + */ +DECLHIDDEN(int) rtR0MemObjNativeAllocPhys(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest, size_t uAlignment, + const char *pszTag); + +/** + * Allocates non-contiguous page aligned physical memory without (necessarily) any kernel mapping. + * + * @returns IPRT status code. + * @retval VERR_NOT_SUPPORTED if it's not possible to allocated unmapped + * physical memory on this platform. + * @param ppMem Where to store the ring-0 memory object handle. + * @param cb Number of bytes to allocate, page aligned. + * @param PhysHighest The highest permitable address (inclusive). + * NIL_RTHCPHYS if any address is acceptable. + * @param pszTag Allocation tag used for statistics and such. + */ +DECLHIDDEN(int) rtR0MemObjNativeAllocPhysNC(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest, const char *pszTag); + +/** + * Creates a page aligned, contiguous, physical memory object. + * + * @returns IPRT status code. + * @param ppMem Where to store the ring-0 memory object handle. + * @param Phys The physical address to start at, page aligned. + * @param cb The size of the object in bytes, page aligned. + * @param uCachePolicy One of the RTMEM_CACHE_XXX modes. + * @param pszTag Allocation tag used for statistics and such. + */ +DECLHIDDEN(int) rtR0MemObjNativeEnterPhys(PPRTR0MEMOBJINTERNAL ppMem, RTHCPHYS Phys, size_t cb, uint32_t uCachePolicy, + const char *pszTag); + +/** + * Reserves kernel virtual address space. + * + * @returns IPRT status code. + * Return VERR_NOT_SUPPORTED to indicate that the user should employ fallback strategies. + * @param ppMem Where to store the ring-0 memory object handle. + * @param pvFixed Requested address. (void *)-1 means any address. This matches uAlignment if specified. + * @param cb The number of bytes to reserve, page aligned. + * @param uAlignment The alignment of the reserved memory; PAGE_SIZE, _2M or _4M. + * @param pszTag Allocation tag used for statistics and such. + */ +DECLHIDDEN(int) rtR0MemObjNativeReserveKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pvFixed, size_t cb, size_t uAlignment, + const char *pszTag); + +/** + * Reserves user virtual address space in the current process. + * + * @returns IPRT status code. + * @param ppMem Where to store the ring-0 memory object handle. + * @param R3PtrFixed Requested address. (RTR3PTR)-1 means any address. This matches uAlignment if specified. + * @param cb The number of bytes to reserve, page aligned. + * @param uAlignment The alignment of the reserved memory; PAGE_SIZE, _2M or _4M. + * @param R0Process The process to reserve the memory in. + * @param pszTag Allocation tag used for statistics and such. + */ +DECLHIDDEN(int) rtR0MemObjNativeReserveUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3PtrFixed, size_t cb, size_t uAlignment, + RTR0PROCESS R0Process, const char *pszTag); + +/** + * Maps a memory object into user virtual address space in the current process. + * + * @returns IPRT status code. + * @retval VERR_NOT_SUPPORTED see RTR0MemObjMapKernelEx. + * + * @param ppMem Where to store the ring-0 memory object handle of the mapping object. + * @param pMemToMap The object to be map. + * @param pvFixed Requested address. (void *)-1 means any address. This matches uAlignment if specified. + * @param uAlignment The alignment of the reserved memory; PAGE_SIZE, _2M or _4M. + * @param fProt Combination of RTMEM_PROT_* flags (except RTMEM_PROT_NONE). + * @param offSub Where in the object to start mapping. If non-zero + * the value must be page aligned and cbSub must be + * non-zero as well. + * @param cbSub The size of the part of the object to be mapped. If + * zero the entire object is mapped. The value must be + * page aligned. + * @param pszTag Allocation tag used for statistics and such. + */ +DECLHIDDEN(int) rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment, + unsigned fProt, size_t offSub, size_t cbSub, const char *pszTag); + +/** + * Maps a memory object into user virtual address space in the current process. + * + * @returns IPRT status code. + * @param ppMem Where to store the ring-0 memory object handle of the mapping object. + * @param pMemToMap The object to be map. + * @param R3PtrFixed Requested address. (RTR3PTR)-1 means any address. This matches uAlignment if specified. + * @param uAlignment The alignment of the reserved memory; PAGE_SIZE, _2M or _4M. + * @param fProt Combination of RTMEM_PROT_* flags (except RTMEM_PROT_NONE). + * @param R0Process The process to map the memory into. + * @param offSub Where in the object to start mapping. If non-zero + * the value must be page aligned and cbSub must be + * non-zero as well. + * @param cbSub The size of the part of the object to be mapped. If + * zero the entire object is mapped. The value must be + * page aligned. + * @param pszTag Allocation tag used for statistics and such. + */ +DECLHIDDEN(int) rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, PRTR0MEMOBJINTERNAL pMemToMap, RTR3PTR R3PtrFixed, + size_t uAlignment, unsigned fProt, RTR0PROCESS R0Process, size_t offSub, size_t cbSub, + const char *pszTag); + +/** + * Change the page level protection of one or more pages in a memory object. + * + * @returns IPRT status code. + * @retval VERR_NOT_SUPPORTED see RTR0MemObjProtect. + * + * @param pMem The memory object. + * @param offSub Offset into the memory object. Page aligned. + * @param cbSub Number of bytes to change the protection of. Page + * aligned. + * @param fProt Combination of RTMEM_PROT_* flags. + */ +DECLHIDDEN(int) rtR0MemObjNativeProtect(PRTR0MEMOBJINTERNAL pMem, size_t offSub, size_t cbSub, uint32_t fProt); + +/** + * Get the physical address of an page in the memory object. + * + * @returns The physical address. + * @returns NIL_RTHCPHYS if the object doesn't contain fixed physical pages. + * @returns NIL_RTHCPHYS if the iPage is out of range. + * @returns NIL_RTHCPHYS if the object handle isn't valid. + * @param pMem The ring-0 memory object handle. + * @param iPage The page number within the object (valid). + */ +DECLHIDDEN(RTHCPHYS) rtR0MemObjNativeGetPagePhysAddr(PRTR0MEMOBJINTERNAL pMem, size_t iPage); + +DECLHIDDEN(PRTR0MEMOBJINTERNAL) rtR0MemObjNew(size_t cbSelf, RTR0MEMOBJTYPE enmType, void *pv, size_t cb, const char *pszTag); +DECLHIDDEN(void) rtR0MemObjDelete(PRTR0MEMOBJINTERNAL pMem); +DECLHIDDEN(int) rtR0MemObjFallbackAllocLarge(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, size_t cbLargePage, uint32_t fFlags, + const char *pszTag); + +/** @} */ + +RT_C_DECLS_END + +#endif /* !IPRT_INCLUDED_INTERNAL_memobj_h */ + diff --git a/src/VBox/Runtime/include/internal/mp.h b/src/VBox/Runtime/include/internal/mp.h new file mode 100644 index 00000000..d5aa0fea --- /dev/null +++ b/src/VBox/Runtime/include/internal/mp.h @@ -0,0 +1,95 @@ +/* $Id: mp.h $ */ +/** @file + * IPRT - Internal RTMp header + */ + +/* + * Copyright (C) 2016-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_INTERNAL_mp_h +#define IPRT_INCLUDED_INTERNAL_mp_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/assert.h> +#include <iprt/mp.h> + +RT_C_DECLS_BEGIN + + +#ifdef RT_OS_WINDOWS +/** @todo Return the processor group + number instead. + * Unfortunately, DTrace and HM makes the impossible for the time being as it + * seems to be making the stupid assumption that idCpu == iCpuSet. */ +#if 0 +# define IPRT_WITH_RTCPUID_AS_GROUP_AND_NUMBER +#endif + +# ifdef IPRT_WITH_RTCPUID_AS_GROUP_AND_NUMBER + +/** @def RTMPCPUID_FROM_GROUP_AND_NUMBER + * Creates the RTCPUID value. + * + * @remarks We Increment a_uGroup by 1 to make sure the ID is never the same as + * the CPU set index. + * + * @remarks We put the group in the top to make it easy to construct the MAX ID. + * For that reason we also just use 8 bits for the processor number, as + * it keeps the range small. + */ +# define RTMPCPUID_FROM_GROUP_AND_NUMBER(a_uGroup, a_uGroupMember) \ + ( (uint8_t)(a_uGroupMember) | (((uint32_t)(a_uGroup) + 1) << 8) ) + +/** Extracts the group number from a RTCPUID value. */ +DECLINLINE(uint16_t) rtMpCpuIdGetGroup(RTCPUID idCpu) +{ + Assert(idCpu != NIL_RTCPUID); + uint16_t idxGroup = idCpu >> 8; + Assert(idxGroup != 0); + return idxGroup - 1; +} + +/** Extracts the group member number from a RTCPUID value. */ +DECLINLINE(uint8_t) rtMpCpuIdGetGroupMember(RTCPUID idCpu) +{ + Assert(idCpu != NIL_RTCPUID); + return (uint8_t)idCpu; +} + +# endif /* IPRT_WITH_RTCPUID_AS_GROUP_AND_NUMBER */ +#endif /* RT_OS_WINDOWS */ + + +RT_C_DECLS_END + +#endif /* !IPRT_INCLUDED_INTERNAL_mp_h */ + diff --git a/src/VBox/Runtime/include/internal/nocrt.h b/src/VBox/Runtime/include/internal/nocrt.h new file mode 100644 index 00000000..ad20e50e --- /dev/null +++ b/src/VBox/Runtime/include/internal/nocrt.h @@ -0,0 +1,103 @@ +/* $Id: nocrt.h $ */ +/** @file + * IPRT - Internal header for miscellaneous global defs and types. + */ + +/* + * Copyright (C) 2009-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_INTERNAL_nocrt_h +#define IPRT_INCLUDED_INTERNAL_nocrt_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include "internal/iprt.h" +#include <iprt/list.h> + + +/** + * No-CRT thread data. + */ +typedef struct RTNOCRTTHREADDATA +{ + /** Used by kAllocType_Heap for DLL unload cleanup. */ + RTLISTNODE ListEntry; + /** How this structure was allocated. */ + enum + { + /** Invalid zero entry. */ + kAllocType_Invalid = 0, + /** Embedded in RTTHREADINT. */ + kAllocType_Embedded, + /** Preallocated static array. */ + kAllocType_Static, + /** It's on the heap. */ + kAllocType_Heap, + /** Cleanup dummy. */ + kAllocType_CleanupDummy, + /** End of valid values. */ + kAllocType_End + } enmAllocType; + + /** errno variable. */ + int iErrno; + /** strtok internal variable. */ + char *pszStrToken; + +} RTNOCRTTHREADDATA; +/** Pointer to no-CRT per-thread data. */ +typedef RTNOCRTTHREADDATA *PRTNOCRTTHREADDATA; + + +extern RTTLS volatile g_iTlsRtNoCrtPerThread; +extern RTNOCRTTHREADDATA g_RtNoCrtPerThreadDummy; + +PRTNOCRTTHREADDATA rtNoCrtThreadDataGet(void); + +#ifdef IN_RING3 +void rtNoCrtFatalWriteBegin(const char *pchMsg, size_t cchMsg); +void rtNoCrtFatalWrite(const char *pchMsg, size_t cchMsg); +void rtNoCrtFatalWriteEnd(const char *pchMsg, size_t cchMsg); +void rtNoCrtFatalWriteStr(const char *pszMsg); +void rtNoCrtFatalWritePtr(void const *pv); +void rtNoCrtFatalWriteX64(uint64_t uValue); +void rtNoCrtFatalWriteX32(uint32_t uValue); +void rtNoCrtFatalWriteRc(int rc); +void rtNoCrtFatalWriteWinRc(uint32_t rc); + +void rtNoCrtFatalMsg(const char *pchMsg, size_t cchMsg); +void rtNoCrtFatalMsgWithRc(const char *pchMsg, size_t cchMsg, int rc); +#endif + + +#endif /* !IPRT_INCLUDED_INTERNAL_nocrt_h */ + diff --git a/src/VBox/Runtime/include/internal/openssl-post.h b/src/VBox/Runtime/include/internal/openssl-post.h new file mode 100644 index 00000000..2444789d --- /dev/null +++ b/src/VBox/Runtime/include/internal/openssl-post.h @@ -0,0 +1,42 @@ +/* $Id: openssl-post.h $ */ +/** @file + * IPRT - Internal header to be included after a block of openssl includes. + */ + +/* + * Copyright (C) 2020-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +/* No guard or pragma once! */ + +#if defined(_MSC_VER) && defined(__cplusplus) +# pragma warning(pop) +#endif + diff --git a/src/VBox/Runtime/include/internal/openssl-pre.h b/src/VBox/Runtime/include/internal/openssl-pre.h new file mode 100644 index 00000000..d4c7ece2 --- /dev/null +++ b/src/VBox/Runtime/include/internal/openssl-pre.h @@ -0,0 +1,49 @@ +/* $Id: openssl-pre.h $ */ +/** @file + * IPRT - Internal header to be included before a block of openssl includes. + */ + +/* + * Copyright (C) 2020-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +/* No guard or pragma once! */ + +#if defined(_MSC_VER) && defined(__cplusplus) +# pragma warning(push) +# pragma warning(disable:4668) /* openssl-1.1.0e-x86\include\openssl/opensslconf.h(104) : warning C4668: '__GNUC__' is not defined as a preprocessor macro, replacing with '0' for '#if/#elif' */ +# if _MSC_VER >= 1700 /*RT_MSC_VER_VC120*/ /** @todo check this. 1600 (VS2010) doesn't know it and warns. */ +# pragma warning(disable:5031) /* warning C5031: #pragma warning(pop): likely mismatch, popping warning state pushed in different file */ +# endif +# if _MSC_VER >= 1900 /*RT_MSC_VER_VC140*/ +# pragma warning(disable:5039) /* Passing callbacks that may throw C++ exception to nothrowing extern "C" functions. */ +# endif +#endif + diff --git a/src/VBox/Runtime/include/internal/path.h b/src/VBox/Runtime/include/internal/path.h new file mode 100644 index 00000000..964b9630 --- /dev/null +++ b/src/VBox/Runtime/include/internal/path.h @@ -0,0 +1,158 @@ +/* $Id: path.h $ */ +/** @file + * IPRT - RTPath Internal header. + */ + +/* + * Copyright (C) 2006-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_INTERNAL_path_h +#define IPRT_INCLUDED_INTERNAL_path_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/cdefs.h> +#include <iprt/param.h> + +RT_C_DECLS_BEGIN + +#if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS) +# define HAVE_UNC 1 +# define HAVE_DRIVE 1 +#endif + +/** The name of the environment variable that is used to override the default + * codeset used when talking to the file systems. This is only available on + * Mac OS X and UNIX systems. */ +#define RTPATH_CODESET_ENV_VAR "IPRT_PATH_CODESET" + + +DECLHIDDEN(size_t) rtPathRootSpecLen(const char *pszPath); +DECLHIDDEN(size_t) rtPathVolumeSpecLen(const char *pszPath); +DECLHIDDEN(int) rtPathPosixRename(const char *pszSrc, const char *pszDst, unsigned fRename, RTFMODE fFileType); +DECLHIDDEN(int) rtPathWin32MoveRename(const char *pszSrc, const char *pszDst, uint32_t fFlags, RTFMODE fFileType); + + +/** + * Converts a path from IPRT to native representation. + * + * This may involve querying filesystems what codeset they speak and so forth. + * + * @returns IPRT status code. + * @param ppszNativePath Where to store the pointer to the native path. + * Free by calling rtPathFreeHost(). NULL on failure. + * Can be the same as pszPath. + * @param pszPath The path to convert. + * @param pszBasePath What pszPath is relative to. NULL if current + * directory. + * + * @remark This function is not available on hosts using something else than + * byte sequences as names (eg win32). + */ +int rtPathToNative(char const **ppszNativePath, const char *pszPath, const char *pszBasePath); + +/** + * Frees a native path returned by rtPathToNative() or rtPathToNativeEx(). + * + * @param pszNativePath The host path to free. NULL allowed. + * @param pszPath The original path. This is for checking if + * rtPathToNative returned the pointer to the original. + * + * @remark This function is not available on hosts using something else than + * byte sequences as names (eg win32). + */ +void rtPathFreeNative(char const *pszNativePath, const char *pszPath); + +/** + * Converts a path from the native to the IPRT representation. + * + * @returns IPRT status code. + * @param ppszPath Where to store the pointer to the IPRT path. + * Free by calling rtPathFreeIprt(). NULL on failure. + * @param pszNativePath The native path to convert. + * @param pszBasePath What pszNativePath is relative to - in IPRT + * representation. NULL if current directory. + * + * @remark This function is not available on hosts using something else than + * byte sequences as names (eg win32). + */ +int rtPathFromNative(const char **ppszPath, const char *pszNativePath, const char *pszBasePath); + +/** + * Frees a path returned by rtPathFromNative or rtPathFromNativeEx. + * + * @param pszPath The returned path. + * @param pszNativePath The original path. + */ +void rtPathFreeIprt(const char *pszPath, const char *pszNativePath); + +/** + * Convert a path from the native representation to the IPRT one, using the + * specified path buffer. + * + * @returns VINF_SUCCESS, VERR_BUFFER_OVERFLOW, and recoding errors. + * + * @param pszPath The output buffer. + * @param cbPath The size of the output buffer. + * @param pszNativePath The path to convert. + * @param pszBasePath What pszNativePath is relative to - in IPRT + * representation. NULL if current directory. + */ +int rtPathFromNativeCopy(char *pszPath, size_t cbPath, const char *pszNativePath, const char *pszBasePath); + +/** + * Convert a path from the native representation to the IPRT one, allocating a + * string buffer for the result. + * + * @returns VINF_SUCCESS, VERR_NO_STR_MEMORY, and recoding errors. + * + * @param ppszPath Where to return the pointer to the IPRT path. Must + * be freed by calling RTStrFree. + * @param pszNativePath The path to convert. + * @param pszBasePath What pszNativePath is relative to - in IPRT + * representation. NULL if current directory. + */ +int rtPathFromNativeDup(char **ppszPath, const char *pszNativePath, const char *pszBasePath); + + +#if defined(RT_OS_WINDOWS) && defined(IPRT_INCLUDED_fs_h) && defined(UNICODE_NULL) +DECLHIDDEN(int) rtPathNtQueryInfoWorker(HANDLE hRootDir, struct _UNICODE_STRING *pNtName, PRTFSOBJINFO pObjInfo, + RTFSOBJATTRADD enmAdditionalAttribs, uint32_t fFlags, const char *pszPath); +DECLHIDDEN(int) rtPathNtQueryInfoFromHandle(HANDLE hFile, void *pvBuf, size_t cbBuf, PRTFSOBJINFO pObjInfo, + RTFSOBJATTRADD enmAddAttr, const char *pszPath, ULONG uReparseTag); +#endif + + +RT_C_DECLS_END + +#endif /* !IPRT_INCLUDED_INTERNAL_path_h */ + diff --git a/src/VBox/Runtime/include/internal/pipe.h b/src/VBox/Runtime/include/internal/pipe.h new file mode 100644 index 00000000..5f63c5a6 --- /dev/null +++ b/src/VBox/Runtime/include/internal/pipe.h @@ -0,0 +1,138 @@ +/* $Id: pipe.h $ */ +/** @file + * IPRT - Internal RTPipe header. + */ + +/* + * Copyright (C) 2010-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_INTERNAL_pipe_h +#define IPRT_INCLUDED_INTERNAL_pipe_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/pipe.h> + +RT_C_DECLS_BEGIN + +/** + * Internal RTPollSetAdd helper that returns the handle that should be added to + * the pollset. + * + * @returns Valid handle on success, INVALID_HANDLE_VALUE on failure. + * @param hPipe The pipe handle. + * @param fEvents The events we're polling for. + * @param phNative Where to put the primary handle. + */ +int rtPipePollGetHandle(RTPIPE hPipe, uint32_t fEvents, PRTHCINTPTR phNative); + +/** + * Internal RTPoll helper that polls the pipe handle and, if @a fNoWait is + * clear, starts whatever actions we've got running during the poll call. + * + * @returns 0 if no pending events, actions initiated if @a fNoWait is clear. + * Event mask (in @a fEvents) and no actions if the handle is ready + * already. + * UINT32_MAX (asserted) if the pipe handle is busy in I/O or a + * different poll set. + * + * @param hPipe The pipe handle. + * @param hPollSet The poll set handle (for access checks). + * @param fEvents The events we're polling for. + * @param fFinalEntry Set if this is the final entry for this handle + * in this poll set. This can be used for dealing + * with duplicate entries. + * @param fNoWait Set if it's a zero-wait poll call. Clear if + * we'll wait for an event to occur. + */ +uint32_t rtPipePollStart(RTPIPE hPipe, RTPOLLSET hPollSet, uint32_t fEvents, bool fFinalEntry, bool fNoWait); + +/** + * Called after a WaitForMultipleObjects returned in order to check for pending + * events and stop whatever actions that rtPipePollStart() initiated. + * + * @returns Event mask or 0. + * + * @param hPipe The pipe handle. + * @param fEvents The events we're polling for. + * @param fFinalEntry Set if this is the final entry for this handle + * in this poll set. This can be used for dealing + * with duplicate entries. Only keep in mind that + * this method is called in reverse order, so the + * first call will have this set (when the entire + * set was processed). + * @param fHarvestEvents Set if we should check for pending events. + */ +uint32_t rtPipePollDone(RTPIPE hPipe, uint32_t fEvents, bool fFinalEntry, bool fHarvestEvents); + + +/** + * Fakes basic query info data for RTPipeQueryInfo. + * + * @param pObjInfo The output structure. + * @param enmAddAttr The extra attribute. + * @param fReadPipe Set if read pipe, clear if write pipe. + */ +DECLINLINE(void) rtPipeFakeQueryInfo(PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr, bool fReadPipe) +{ + RT_ZERO(*pObjInfo); + if (fReadPipe) + pObjInfo->Attr.fMode = RTFS_TYPE_FIFO | RTFS_UNIX_IRUSR | RTFS_DOS_READONLY; + else + pObjInfo->Attr.fMode = RTFS_TYPE_FIFO | RTFS_UNIX_IWUSR; + pObjInfo->Attr.enmAdditional = enmAddAttr; + switch (enmAddAttr) + { + case RTFSOBJATTRADD_UNIX: + pObjInfo->Attr.u.Unix.cHardlinks = 1; + break; + case RTFSOBJATTRADD_UNIX_OWNER: + pObjInfo->Attr.u.UnixOwner.uid = NIL_RTUID; + break; + case RTFSOBJATTRADD_UNIX_GROUP: + pObjInfo->Attr.u.UnixGroup.gid = NIL_RTGID; + break; + case RTFSOBJATTRADD_EASIZE: + break; + case RTFSOBJATTRADD_32BIT_SIZE_HACK: + case RTFSOBJATTRADD_NOTHING: + /* shut up gcc. */ + break; + /* no default, want warnings. */ + } +} + + +RT_C_DECLS_END + +#endif /* !IPRT_INCLUDED_INTERNAL_pipe_h */ + diff --git a/src/VBox/Runtime/include/internal/process.h b/src/VBox/Runtime/include/internal/process.h new file mode 100644 index 00000000..52cd1250 --- /dev/null +++ b/src/VBox/Runtime/include/internal/process.h @@ -0,0 +1,83 @@ +/* $Id: process.h $ */ +/** @file + * IPRT - Internal RTProc header. + */ + +/* + * Copyright (C) 2006-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_INTERNAL_process_h +#define IPRT_INCLUDED_INTERNAL_process_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/process.h> +#include <iprt/param.h> + +RT_C_DECLS_BEGIN + +extern DECL_HIDDEN_DATA(RTPROCESS) g_ProcessSelf; +extern DECL_HIDDEN_DATA(RTPROCPRIORITY) g_enmProcessPriority; +extern DECL_HIDDEN_DATA(char) g_szrtProcExePath[RTPATH_MAX]; +extern DECL_HIDDEN_DATA(size_t) g_cchrtProcExePath; +extern DECL_HIDDEN_DATA(size_t) g_cchrtProcExeDir; +extern DECL_HIDDEN_DATA(size_t) g_offrtProcName; + +/** + * Validates and sets the process priority. + * + * This will check that all rtThreadNativeSetPriority() will success for all the + * thread types when applied to the current thread. + * + * @returns IPRT status code. + * @param enmPriority The priority to validate and set. + * + * @remark Located in sched. + */ +DECLHIDDEN(int) rtProcNativeSetPriority(RTPROCPRIORITY enmPriority); + +/** + * Determines the full path to the executable image. + * + * This is called by rtR3Init. + * + * @returns IPRT status code. + * + * @param pszPath Pointer to the g_szrtProcExePath buffer. + * @param cchPath The size of the buffer. + */ +DECLHIDDEN(int) rtProcInitExePath(char *pszPath, size_t cchPath); + +RT_C_DECLS_END + +#endif /* !IPRT_INCLUDED_INTERNAL_process_h */ + diff --git a/src/VBox/Runtime/include/internal/rand.h b/src/VBox/Runtime/include/internal/rand.h new file mode 100644 index 00000000..b5becdaf --- /dev/null +++ b/src/VBox/Runtime/include/internal/rand.h @@ -0,0 +1,188 @@ +/* $Id: rand.h $ */ +/** @file + * IPRT - Internal RTRand header + */ + +/* + * Copyright (C) 2006-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_INTERNAL_rand_h +#define IPRT_INCLUDED_INTERNAL_rand_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/types.h> +#include <iprt/critsect.h> + +/** Pointer to a random number generator instance. */ +typedef struct RTRANDINT *PRTRANDINT; + +/** + * Random number generator instance. + * + * @remarks Not sure if it makes sense to have three random getters... + */ +typedef struct RTRANDINT +{ + /** Magic value (RTRANDINT_MAGIC). */ + uint32_t u32Magic; +#if 0 /** @todo later. */ + /** Fast mutex semaphore that serializes the access, this is optional. */ + PRTCRITSECT pCritSect; +#endif + + /** + * Generates random bytes. + * + * @param pThis Pointer to the instance data. + * @param pb Where to store the bytes. + * @param cb The number of bytes to produce. + */ + DECLCALLBACKMEMBER(void , pfnGetBytes,(PRTRANDINT pThis, uint8_t *pb, size_t cb)); + + /** + * Generates a unsigned 32-bit random number. + * + * @returns The random number. + * @param pThis Pointer to the instance data. + * @param u32First The first number in the range. + * @param u32Last The last number in the range (i.e. inclusive). + */ + DECLCALLBACKMEMBER(uint32_t, pfnGetU32,(PRTRANDINT pThis, uint32_t u32First, uint32_t u32Last)); + + /** + * Generates a unsigned 64-bit random number. + * + * @returns The random number. + * @param pThis Pointer to the instance data. + * @param u64First The first number in the range. + * @param u64Last The last number in the range (i.e. inclusive). + */ + DECLCALLBACKMEMBER(uint64_t, pfnGetU64,(PRTRANDINT pThis, uint64_t u64First, uint64_t u64Last)); + + /** + * Generic seeding. + * + * @returns IPRT status code. + * @retval VERR_NOT_SUPPORTED if it isn't a pseudo generator. + * + * @param pThis Pointer to the instance data. + * @param u64Seed The seed. + */ + DECLCALLBACKMEMBER(int, pfnSeed,(PRTRANDINT pThis, uint64_t u64Seed)); + + /** + * Save the current state of a pseudo generator. + * + * This can be use to save the state so it can later be resumed at the same + * position. + * + * @returns IPRT status code. + * @retval VINF_SUCCESS on success. *pcbState contains the length of the + * returned string and pszState contains the state string. + * @retval VERR_BUFFER_OVERFLOW if the supplied buffer is too small. *pcbState + * will contain the necessary buffer size. + * @retval VERR_NOT_SUPPORTED by non-psuedo generators. + * + * @param pThis Pointer to the instance data. + * @param pszState Where to store the state. The returned string will be + * null terminated and printable. + * @param pcbState The size of the buffer pszState points to on input, the + * size required / used on return (including the + * terminator, thus the 'cb' instead of 'cch'). + */ + DECLCALLBACKMEMBER(int, pfnSaveState,(PRTRANDINT pThis, char *pszState, size_t *pcbState)); + + /** + * Restores the state of a pseudo generator. + * + * The state must have been obtained using pfnGetState. + * + * @returns IPRT status code. + * @retval VERR_PARSE_ERROR if the state string is malformed. + * @retval VERR_NOT_SUPPORTED by non-psuedo generators. + * + * @param pThis Pointer to the instance data. + * @param pszState The state to load. + */ + DECLCALLBACKMEMBER(int, pfnRestoreState,(PRTRANDINT pThis, char const *pszState)); + + /** + * Destroys the instance. + * + * The callee is responsible for freeing all resources, including + * the instance data. + * + * @returns IPRT status code. State undefined on failure. + * @param pThis Pointer to the instance data. + */ + DECLCALLBACKMEMBER(int, pfnDestroy,(PRTRANDINT pThis)); + + /** Union containing the specific state info for each generator. */ + union + { + struct RTRandParkMiller + { + /** The context. */ + uint32_t u32Ctx; + /** The number of single bits used to fill in the 31st bit. */ + uint32_t u32Bits; + /** The number bits in u32Bits. */ + uint32_t cBits; + } ParkMiller; + + struct RTRandFile + { + /** The file handle (native). */ + intptr_t hFile; + } File; + } u; +} RTRANDINT; + + +RT_C_DECLS_BEGIN + +DECL_HIDDEN_CALLBACK(void) rtRandAdvSynthesizeBytesFromU32(PRTRANDINT pThis, uint8_t *pb, size_t cb); +DECL_HIDDEN_CALLBACK(void) rtRandAdvSynthesizeBytesFromU64(PRTRANDINT pThis, uint8_t *pb, size_t cb); +DECL_HIDDEN_CALLBACK(uint32_t) rtRandAdvSynthesizeU32FromBytes(PRTRANDINT pThis, uint32_t u32First, uint32_t u32Last); +DECL_HIDDEN_CALLBACK(uint32_t) rtRandAdvSynthesizeU32FromU64(PRTRANDINT pThis, uint32_t u32First, uint32_t u32Last); +DECL_HIDDEN_CALLBACK(uint64_t) rtRandAdvSynthesizeU64FromBytes(PRTRANDINT pThis, uint64_t u64First, uint64_t u64Last); +DECL_HIDDEN_CALLBACK(uint64_t) rtRandAdvSynthesizeU64FromU32(PRTRANDINT pThis, uint64_t u64First, uint64_t u64Last); +DECL_HIDDEN_CALLBACK(int) rtRandAdvStubSeed(PRTRANDINT pThis, uint64_t u64Seed); +DECL_HIDDEN_CALLBACK(int) rtRandAdvStubSaveState(PRTRANDINT pThis, char *pszState, size_t *pcbState); +DECL_HIDDEN_CALLBACK(int) rtRandAdvStubRestoreState(PRTRANDINT pThis, char const *pszState); +DECL_HIDDEN_CALLBACK(int) rtRandAdvDefaultDestroy(PRTRANDINT pThis); + +RT_C_DECLS_END + +#endif /* !IPRT_INCLUDED_INTERNAL_rand_h */ + diff --git a/src/VBox/Runtime/include/internal/req.h b/src/VBox/Runtime/include/internal/req.h new file mode 100644 index 00000000..4fbc24aa --- /dev/null +++ b/src/VBox/Runtime/include/internal/req.h @@ -0,0 +1,187 @@ +/* $Id: req.h $ */ +/** @file + * IPRT - Internal RTReq header. + */ + +/* + * Copyright (C) 2006-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_INTERNAL_req_h +#define IPRT_INCLUDED_INTERNAL_req_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/types.h> + + +RT_C_DECLS_BEGIN + +/** + * Request state. + */ +typedef enum RTREQSTATE +{ + /** The state is invalid. */ + RTREQSTATE_INVALID = 0, + /** The request have been allocated and is in the process of being filed. */ + RTREQSTATE_ALLOCATED, + /** The request is queued by the requester. */ + RTREQSTATE_QUEUED, + /** The request is begin processed. */ + RTREQSTATE_PROCESSING, + /** The request has been cancelled. */ + RTREQSTATE_CANCELLED, + /** The request is completed, the requester is begin notified. */ + RTREQSTATE_COMPLETED, + /** The request packet is in the free chain. */ + RTREQSTATE_FREE +} RTREQSTATE; +AssertCompileSize(RTREQSTATE, sizeof(uint32_t)); + + +/** + * RT Request packet. + * + * This is used to request an action in the queue handler thread. + */ +struct RTREQ +{ + /** Magic number (RTREQ_MAGIC). */ + uint32_t u32Magic; + /** Set if the event semaphore is clear. */ + volatile bool fEventSemClear; + /** Set if the push back semaphore should be signaled when the request + * is picked up from the queue. */ + volatile bool fSignalPushBack; + /** Set if pool, clear if queue. */ + volatile bool fPoolOrQueue; + /** IPRT status code for the completed request. */ + volatile int32_t iStatusX; + /** Request state. */ + volatile RTREQSTATE enmState; + /** The reference count. */ + volatile uint32_t cRefs; + + /** Pointer to the next request in the chain. */ + struct RTREQ * volatile pNext; + + union + { + /** Pointer to the pool this packet belongs to. */ + RTREQPOOL hPool; + /** Pointer to the queue this packet belongs to. */ + RTREQQUEUE hQueue; + /** Opaque owner access. */ + void *pv; + } uOwner; + + /** Timestamp take when the request was submitted to a pool. Not used + * for queued request. */ + uint64_t uSubmitNanoTs; + /** Requester completion event sem. */ + RTSEMEVENT EventSem; + /** Request pushback event sem. Allocated lazily. */ + RTSEMEVENTMULTI hPushBackEvt; + /** Flags, RTREQ_FLAGS_*. */ + uint32_t fFlags; + /** Request type. */ + RTREQTYPE enmType; + /** Request specific data. */ + union RTREQ_U + { + /** RTREQTYPE_INTERNAL. */ + struct + { + /** Pointer to the function to be called. */ + PFNRT pfn; + /** Number of arguments. */ + uint32_t cArgs; + /** Array of arguments. */ + uintptr_t aArgs[12]; + } Internal; + } u; +}; + +/** Internal request representation. */ +typedef RTREQ RTREQINT; +/** Pointer to an internal request representation. */ +typedef RTREQINT *PRTREQINT; + +/** + * Internal queue instance. + */ +typedef struct RTREQQUEUEINT +{ + /** Magic value (RTREQQUEUE_MAGIC). */ + uint32_t u32Magic; + /** Set if busy (pending or processing requests). */ + bool volatile fBusy; + /** Head of the request queue (LIFO). Atomic. */ + volatile PRTREQ pReqs; + /** List of requests pending after a non-VINF_SUCCESS status code forced + * RTReqQueueProcess to stop processing requestins. This is in FIFO order. */ + volatile PRTREQ pAlreadyPendingReqs; + /** The last index used during alloc/free. */ + volatile uint32_t iReqFree; + /** Number of free request packets. */ + volatile uint32_t cReqFree; + /** Array of pointers to lists of free request packets. Atomic. */ + volatile PRTREQ apReqFree[9]; + /** Requester event sem. + * The request can use this event semaphore to wait/poll for new requests. + */ + RTSEMEVENT EventSem; +} RTREQQUEUEINT; + +/** Pointer to an internal queue instance. */ +typedef struct RTREQQUEUEINT *PRTREQQUEUEINT; +/** Pointer to a request thread pool instance. */ +typedef struct RTREQPOOLINT *PRTREQPOOLINT; + + +/* req.cpp */ +DECLHIDDEN(int) rtReqAlloc(RTREQTYPE enmType, bool fPoolOrQueue, void *pvOwner, PRTREQ *phReq); +DECLHIDDEN(int) rtReqReInit(PRTREQINT pReq, RTREQTYPE enmType); +DECLHIDDEN(void) rtReqFreeIt(PRTREQINT pReq); +DECLHIDDEN(int) rtReqProcessOne(PRTREQ pReq); + +/* reqpool.cpp / reqqueue.cpp. */ +DECLHIDDEN(void) rtReqQueueSubmit(PRTREQQUEUEINT pQueue, PRTREQINT pReq); +DECLHIDDEN(void) rtReqPoolSubmit(PRTREQPOOLINT pPool, PRTREQINT pReq); +DECLHIDDEN(void) rtReqPoolCancel(PRTREQPOOLINT pPool, PRTREQINT pReq); +DECLHIDDEN(bool) rtReqQueueRecycle(PRTREQQUEUEINT pQueue, PRTREQINT pReq); +DECLHIDDEN(bool) rtReqPoolRecycle(PRTREQPOOLINT pPool, PRTREQINT pReq); + +RT_C_DECLS_END + +#endif /* !IPRT_INCLUDED_INTERNAL_req_h */ + diff --git a/src/VBox/Runtime/include/internal/sched.h b/src/VBox/Runtime/include/internal/sched.h new file mode 100644 index 00000000..bd636c65 --- /dev/null +++ b/src/VBox/Runtime/include/internal/sched.h @@ -0,0 +1,60 @@ +/* $Id: sched.h $ */ +/** @file + * IPRT - Internal RTSched header. + */ + +/* + * Copyright (C) 2006-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_INTERNAL_sched_h +#define IPRT_INCLUDED_INTERNAL_sched_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/thread.h> +#include "internal/process.h" +#include "internal/thread.h" + +RT_C_DECLS_BEGIN + +/** + * Calculate the scheduling properties for all the threads in the default + * process priority, assuming the current thread have the type enmType. + * + * @returns iprt status code. + * @param enmType The thread type to be assumed for the current thread. + */ +DECLHIDDEN(int) rtSchedNativeCalcDefaultPriority(RTTHREADTYPE enmType); + +RT_C_DECLS_END + +#endif /* !IPRT_INCLUDED_INTERNAL_sched_h */ diff --git a/src/VBox/Runtime/include/internal/socket.h b/src/VBox/Runtime/include/internal/socket.h new file mode 100644 index 00000000..85b6ccba --- /dev/null +++ b/src/VBox/Runtime/include/internal/socket.h @@ -0,0 +1,87 @@ +/* $Id: socket.h $ */ +/** @file + * IPRT - Internal Header for RTSocket. + */ + +/* + * Copyright (C) 2010-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_INTERNAL_socket_h +#define IPRT_INCLUDED_INTERNAL_socket_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/cdefs.h> +#include <iprt/types.h> +#include <iprt/net.h> +/* Currently requires a bunch of socket headers. */ + + +/** Native socket handle type. */ +#ifdef RT_OS_WINDOWS +# define RTSOCKETNATIVE SOCKET +#else +# define RTSOCKETNATIVE int +#endif + +/** NIL value for native socket handles. */ +#ifdef RT_OS_WINDOWS +# define NIL_RTSOCKETNATIVE INVALID_SOCKET +#else +# define NIL_RTSOCKETNATIVE (-1) +#endif + + +RT_C_DECLS_BEGIN + +#ifndef IPRT_INTERNAL_SOCKET_POLLING_ONLY +DECLHIDDEN(int) rtSocketResolverError(void); +DECLHIDDEN(int) rtSocketCreateForNative(RTSOCKETINT **ppSocket, RTSOCKETNATIVE hNative, bool fLeaveOpen); +DECLHIDDEN(int) rtSocketCreate(PRTSOCKET phSocket, int iDomain, int iType, int iProtocol, bool fInheritable); +DECLHIDDEN(int) rtSocketCreateTcpPair(RTSOCKET *phServer, RTSOCKET *phClient); +DECLHIDDEN(int) rtSocketBind(RTSOCKET hSocket, PCRTNETADDR pAddr); +DECLHIDDEN(int) rtSocketBindRawAddr(RTSOCKET hSocket, void const *pvAddr, size_t cbAddr); +DECLHIDDEN(int) rtSocketListen(RTSOCKET hSocket, int cMaxPending); +DECLHIDDEN(int) rtSocketAccept(RTSOCKET hSocket, PRTSOCKET phClient, struct sockaddr *pAddr, size_t *pcbAddr); +DECLHIDDEN(int) rtSocketConnect(RTSOCKET hSocket, PCRTNETADDR pAddr, RTMSINTERVAL cMillies); +DECLHIDDEN(int) rtSocketConnectRaw(RTSOCKET hSocket, void const *pvAddr, size_t cbAddr); +DECLHIDDEN(int) rtSocketSetOpt(RTSOCKET hSocket, int iLevel, int iOption, void const *pvValue, int cbValue); +#endif /* IPRT_INTERNAL_SOCKET_POLLING_ONLY */ + +DECLHIDDEN(int) rtSocketPollGetHandle(RTSOCKET hSocket, uint32_t fEvents, PRTHCINTPTR phNative); +DECLHIDDEN(uint32_t) rtSocketPollStart(RTSOCKET hSocket, RTPOLLSET hPollSet, uint32_t fEvents, bool fFinalEntry, bool fNoWait); +DECLHIDDEN(uint32_t) rtSocketPollDone(RTSOCKET hSocket, uint32_t fEvents, bool fFinalEntry, bool fHarvestEvents); + +RT_C_DECLS_END + +#endif /* !IPRT_INCLUDED_INTERNAL_socket_h */ + diff --git a/src/VBox/Runtime/include/internal/strhash.h b/src/VBox/Runtime/include/internal/strhash.h new file mode 100644 index 00000000..82523a86 --- /dev/null +++ b/src/VBox/Runtime/include/internal/strhash.h @@ -0,0 +1,122 @@ +/* $Id: strhash.h $ */ +/** @file + * IPRT - Internal header containing inline string hashing functions. + */ + +/* + * Copyright (C) 2006-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_INTERNAL_strhash_h +#define IPRT_INCLUDED_INTERNAL_strhash_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/types.h> + + +/* sdbm: + This algorithm was created for sdbm (a public-domain reimplementation of + ndbm) database library. it was found to do well in scrambling bits, + causing better distribution of the keys and fewer splits. it also happens + to be a good general hashing function with good distribution. the actual + function is hash(i) = hash(i - 1) * 65599 + str[i]; what is included below + is the faster version used in gawk. [there is even a faster, duff-device + version] the magic constant 65599 was picked out of thin air while + experimenting with different constants, and turns out to be a prime. + this is one of the algorithms used in berkeley db (see sleepycat) and + elsewhere. */ + +/** + * Hash string, return hash + length. + */ +DECLINLINE(uint32_t) sdbm(const char *str, size_t *pcch) +{ + uint8_t *pu8 = (uint8_t *)str; + uint32_t hash = 0; + int c; + + while ((c = *pu8++)) + hash = c + (hash << 6) + (hash << 16) - hash; + + *pcch = (uintptr_t)pu8 - (uintptr_t)str - 1; + return hash; +} + + +/** + * Hash up to N bytes, return hash + hashed length. + */ +DECLINLINE(uint32_t) sdbmN(const char *str, size_t cchMax, size_t *pcch) +{ + uint8_t *pu8 = (uint8_t *)str; + uint32_t hash = 0; + int c; + + while ((c = *pu8++) && cchMax-- > 0) + hash = c + (hash << 6) + (hash << 16) - hash; + + *pcch = (uintptr_t)pu8 - (uintptr_t)str - 1; + return hash; +} + + +/** + * Incremental hashing. + */ +DECLINLINE(uint32_t) sdbmInc(const char *str, uint32_t hash) +{ + uint8_t *pu8 = (uint8_t *)str; + int c; + + while ((c = *pu8++)) + hash = c + (hash << 6) + (hash << 16) - hash; + + return hash; +} + +/** + * Incremental hashing with length limitation. + */ +DECLINLINE(uint32_t) sdbmIncN(const char *psz, size_t cchMax, uint32_t uHash) +{ + uint8_t *pu8 = (uint8_t *)psz; + int c; + + while ((c = *pu8++) && cchMax-- > 0) + uHash = c + (uHash << 6) + (uHash << 16) - uHash; + + return uHash; +} + + +#endif /* !IPRT_INCLUDED_INTERNAL_strhash_h */ + diff --git a/src/VBox/Runtime/include/internal/strict.h b/src/VBox/Runtime/include/internal/strict.h new file mode 100644 index 00000000..65e038e1 --- /dev/null +++ b/src/VBox/Runtime/include/internal/strict.h @@ -0,0 +1,92 @@ +/* $Id: strict.h $ */ +/** @file + * IPRT - Internal Header Defining Strictness Indicators. + */ + +/* + * Copyright (C) 2007-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_INTERNAL_strict_h +#define IPRT_INCLUDED_INTERNAL_strict_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +/** @name Strictness Indicators + * @{ */ + +/** @def RTCRITSECT_STRICT + * Enables strictness checks and lock accounting of the RTCritSect API. + */ +#if (!defined(RTCRITSECT_STRICT) && defined(IN_RING3) && defined(RT_LOCK_STRICT)) || defined(DOXYGEN_RUNNING) +# define RTCRITSECT_STRICT +#endif + +/** @def RTCRITSECTRW_STRICT + * Enables strictness checks and lock accounting of the RTCritSectRw API. + */ +#if (!defined(RTCRITSECTRW_STRICT) && defined(IN_RING3) && defined(RT_LOCK_STRICT)) || defined(DOXYGEN_RUNNING) +# define RTCRITSECTRW_STRICT +#endif + +/** @def RTSEMEVENT_STRICT + * Enables strictness checks and lock accounting of the RTSemEvent API. + */ +#if (!defined(RTSEMEVENT_STRICT) && defined(IN_RING3) && defined(RT_LOCK_STRICT)) || defined(DOXYGEN_RUNNING) +# define RTSEMEVENT_STRICT +#endif + +/** @def RTSEMEVENTMULTI_STRICT + * Enables strictness checks and lock accounting of the RTSemEventMulti API. + */ +#if (!defined(RTSEMEVENTMULTI_STRICT) && defined(IN_RING3) && defined(RT_LOCK_STRICT)) || defined(DOXYGEN_RUNNING) +# define RTSEMEVENTMULTI_STRICT +#endif + +/** @def RTSEMMUTEX_STRICT + * Enables strictness checks and lock accounting of the RTSemMutex API. + */ +#if (!defined(RTSEMMUTEX_STRICT) && defined(IN_RING3) && defined(RT_LOCK_STRICT)) || defined(DOXYGEN_RUNNING) +# define RTSEMMUTEX_STRICT +#endif + + +/** @def RTSEMRW_STRICT + * Enables strictness checks and lock accounting of the RTSemRW API. + */ +#if (!defined(RTSEMRW_STRICT) && defined(IN_RING3) && defined(RT_LOCK_STRICT)) || defined(DOXYGEN_RUNNING) +# define RTSEMRW_STRICT +#endif + + +/** @} */ + +#endif /* !IPRT_INCLUDED_INTERNAL_strict_h */ diff --git a/src/VBox/Runtime/include/internal/string.h b/src/VBox/Runtime/include/internal/string.h new file mode 100644 index 00000000..e6d1e390 --- /dev/null +++ b/src/VBox/Runtime/include/internal/string.h @@ -0,0 +1,124 @@ +/* $Id: string.h $ */ +/** @file + * IPRT - Internal RTStr header. + */ + +/* + * Copyright (C) 2006-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_INTERNAL_string_h +#define IPRT_INCLUDED_INTERNAL_string_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/string.h> + +RT_C_DECLS_BEGIN + +/** @def RTSTR_STRICT + * Enables strict assertions on bad string encodings. + */ +#ifdef DOXYGEN_RUNNING +# define RTSTR_STRICT +#endif +/*#define RTSTR_STRICT*/ + +#ifdef RTSTR_STRICT +# define RTStrAssertMsgFailed(msg) AssertMsgFailed(msg) +# define RTStrAssertMsgReturn(expr, msg, rc) AssertMsgReturn(expr, msg, rc) +#else +# define RTStrAssertMsgFailed(msg) do { } while (0) +# define RTStrAssertMsgReturn(expr, msg, rc) do { if (!(expr)) return rc; } while (0) +#endif + +DECLHIDDEN(size_t) rtStrFormatBadPointer(size_t cch, PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, int cchWidth, + unsigned fFlags, void const *pvStr, char szTmp[64], const char *pszTag, int cchTag); +DECLHIDDEN(size_t) rtstrFormatRt(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, const char **ppszFormat, va_list *pArgs, + int cchWidth, int cchPrecision, unsigned fFlags, char chArgSize); +DECLHIDDEN(size_t) rtstrFormatType(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, const char **ppszFormat, va_list *pArgs, + int cchWidth, int cchPrecision, unsigned fFlags, char chArgSize); + +/** + * Format kernel address into @a pszBuf. + * + * @returns Number of bytes returned. + * @param pszBuf The return buffer. + * @param cbBuf The buffer size. + * @param uPtr The ring-0 pointer value. + * @param cchWidth The specified width, -1 if not given. + * @param cchPrecision The specified precision. + * @param fFlags Format flags, RTSTR_F_XXX. + */ +DECLHIDDEN(size_t) rtStrFormatKernelAddress(char *pszBuf, size_t cbBuf, RTR0INTPTR uPtr, signed int cchWidth, + signed int cchPrecision, unsigned int fFlags); + +#ifdef RT_WITH_ICONV_CACHE +DECLHIDDEN(void) rtStrIconvCacheInit(struct RTTHREADINT *pThread); +DECLHIDDEN(void) rtStrIconvCacheDestroy(struct RTTHREADINT *pThread); +#endif + +/** + * Indexes into RTTHREADINT::ahIconvs + */ +typedef enum RTSTRICONV +{ + /** UTF-8 to the locale codeset (LC_CTYPE). */ + RTSTRICONV_UTF8_TO_LOCALE = 0, + /** The locale codeset (LC_CTYPE) to UTF-8. */ + RTSTRICONV_LOCALE_TO_UTF8, + /** UTF-8 to the filesystem codeset - if different from the locale codeset. */ + RTSTRICONV_UTF8_TO_FS, + /** The filesystem codeset to UTF-8. */ + RTSTRICONV_FS_TO_UTF8, + /** The end of the valid indexes. */ + RTSTRICONV_END +} RTSTRICONV; + +DECLHIDDEN(int) rtStrConvert(const char *pchInput, size_t cchInput, const char *pszInputCS, + char **ppszOutput, size_t cbOutput, const char *pszOutputCS, + unsigned cFactor, RTSTRICONV enmCacheIdx); +DECLHIDDEN(void) rtStrLocalCacheInit(void **ppvTmpCache); +DECLHIDDEN(int) rtStrLocalCacheConvert(const char *pchInput, size_t cchInput, const char *pszInputCS, + char **ppszOutput, size_t cbOutput, const char *pszOutputCS, + void **ppvTmpCache); +DECLHIDDEN(void) rtStrLocalCacheDelete(void **ppvTmpCache); +DECLHIDDEN(const char *) rtStrGetLocaleCodeset(void); +DECLHIDDEN(bool) rtStrIsLocaleCodesetUtf8(void); +DECLHIDDEN(bool) rtStrIsCodesetUtf8(const char *pszCodeset); +DECLHIDDEN(int) rtUtf8Length(const char *psz, size_t cch, size_t *pcuc, size_t *pcchActual); + +DECLHIDDEN(int) rtStrToIpAddr6Str(const char *psz, char *pszAddrOut, size_t addrOutSize, char *pszPortOut, size_t portOutSize, bool followRfc); + +RT_C_DECLS_END + +#endif /* !IPRT_INCLUDED_INTERNAL_string_h */ + diff --git a/src/VBox/Runtime/include/internal/thread.h b/src/VBox/Runtime/include/internal/thread.h new file mode 100644 index 00000000..92af0569 --- /dev/null +++ b/src/VBox/Runtime/include/internal/thread.h @@ -0,0 +1,325 @@ +/* $Id: thread.h $ */ +/** @file + * IPRT - Internal RTThread header. + */ + +/* + * Copyright (C) 2006-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_INTERNAL_thread_h +#define IPRT_INCLUDED_INTERNAL_thread_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/types.h> +#include <iprt/thread.h> +#include <iprt/avl.h> +#ifdef IN_RING3 +# include <iprt/process.h> +# include <iprt/critsect.h> +#endif +#include "internal/lockvalidator.h" +#include "internal/magics.h" +#ifdef RT_WITH_ICONV_CACHE +# include "internal/string.h" +#endif +#if defined(IPRT_NO_CRT) && defined(IN_RING3) +# include "internal/nocrt.h" +#endif + +RT_C_DECLS_BEGIN + + +#ifdef IPRT_WITH_GENERIC_TLS +/** The number of TLS entries for the generic implementation. */ +# define RTTHREAD_TLS_ENTRIES 64 +#endif + +/** + * Internal representation of a thread. + */ +typedef struct RTTHREADINT +{ + /** Avl node core - the key is the native thread id. */ + AVLPVNODECORE Core; + /** Magic value (RTTHREADINT_MAGIC). */ + uint32_t u32Magic; + /** Reference counter. */ + uint32_t volatile cRefs; + /** The current thread state. */ + RTTHREADSTATE volatile enmState; + /** Set when really sleeping. */ + bool volatile fReallySleeping; +#if defined(RT_OS_WINDOWS) && defined(IN_RING3) + /** The thread handle + * This is not valid until the create function has returned! */ + uintptr_t hThread; +#endif +#if defined(RT_OS_LINUX) && defined(IN_RING3) + /** The thread ID. + * This is not valid before rtThreadMain has been called by the new thread. */ + pid_t tid; +#endif +#if defined(RT_OS_SOLARIS) && defined(IN_RING0) + /** Debug thread ID needed for thread_join. */ + uint64_t tid; +#endif + /** The user event semaphore. */ + RTSEMEVENTMULTI EventUser; + /** The terminated event semaphore. */ + RTSEMEVENTMULTI EventTerminated; + /** The thread type. */ + RTTHREADTYPE enmType; + /** The thread creation flags. (RTTHREADFLAGS) */ + unsigned fFlags; + /** Internal flags. (RTTHREADINT_FLAGS_ *) */ + uint32_t fIntFlags; + /** The result code. */ + int rc; + /** Thread function. */ + PFNRTTHREAD pfnThread; + /** Thread function argument. */ + void *pvUser; + /** Actual stack size. */ + size_t cbStack; +#ifdef IN_RING3 + /** The lock validator data. */ + RTLOCKVALPERTHREAD LockValidator; +#endif /* IN_RING3 */ +#ifdef RT_WITH_ICONV_CACHE + /** Handle cache for iconv. + * @remarks ASSUMES sizeof(void *) >= sizeof(iconv_t). */ + void *ahIconvs[RTSTRICONV_END]; +#endif +#ifdef IPRT_WITH_GENERIC_TLS + /** The TLS entries for this thread. */ + void *apvTlsEntries[RTTHREAD_TLS_ENTRIES]; +#endif + /** Thread name. */ + char szName[RTTHREAD_NAME_LEN]; +#if defined(IPRT_NO_CRT) && defined(IN_RING3) + /** No-CRT per thread data. */ + RTNOCRTTHREADDATA NoCrt; +#endif +} RTTHREADINT; +/** Pointer to the internal representation of a thread. */ +typedef RTTHREADINT *PRTTHREADINT; + + +/** @name RTTHREADINT::fIntFlags Masks and Bits. + * @{ */ +/** Set if the thread is an alien thread. + * Clear if the thread was created by IPRT. */ +#define RTTHREADINT_FLAGS_ALIEN RT_BIT(0) +/** Set if the thread has terminated. + * Clear if the thread is running. */ +#define RTTHREADINT_FLAGS_TERMINATED RT_BIT(1) +/** This bit is set if the thread is in the AVL tree. */ +#define RTTHREADINT_FLAG_IN_TREE_BIT 2 +/** @copydoc RTTHREADINT_FLAG_IN_TREE_BIT */ +#define RTTHREADINT_FLAG_IN_TREE RT_BIT(RTTHREADINT_FLAG_IN_TREE_BIT) +/** Set if it's the main thread. */ +#define RTTHREADINT_FLAGS_MAIN RT_BIT(3) +/** @} */ + +/** Counters for each thread type. */ +extern DECL_HIDDEN_DATA(uint32_t volatile) g_acRTThreadTypeStats[RTTHREADTYPE_END]; + + +/** + * Initialize the native part of the thread management. + * + * Generally a TLS entry will be allocated at this point (Ring-3). + * + * @returns iprt status code. + */ +DECLHIDDEN(int) rtThreadNativeInit(void); + +#ifdef IN_RING3 +/** + * Called when IPRT was first initialized in unobtrusive mode and later changed + * to obtrustive. + * + * This is only applicable in ring-3. + */ +DECLHIDDEN(void) rtThreadNativeReInitObtrusive(void); +#endif + +/** + * Create a native thread. + * This creates the thread as described in pThreadInt and stores the thread id in *pThread. + * + * @returns iprt status code. + * @param pThreadInt The thread data structure for the thread. + * @param pNativeThread Where to store the native thread identifier. + */ +DECLHIDDEN(int) rtThreadNativeCreate(PRTTHREADINT pThreadInt, PRTNATIVETHREAD pNativeThread); + +/** + * Adopts a thread, this is called immediately after allocating the + * thread structure. + * + * @param pThread Pointer to the thread structure. + */ +DECLHIDDEN(int) rtThreadNativeAdopt(PRTTHREADINT pThread); + +/** + * Called from rtThreadDestroy so that the TLS entry and any native data in the + * thread structure can be cleared. + * + * @param pThread The thread structure. + */ +DECLHIDDEN(void) rtThreadNativeDestroy(PRTTHREADINT pThread); + +#ifdef IN_RING3 +/** + * Called to check whether the thread is still alive or not before we start + * waiting. + * + * This is a kludge to deal with windows threads being killed wholesale in + * certain process termination scenarios and we don't want to hang the last + * thread because it's waiting on the semaphore of a dead thread. + * + * @returns true if alive, false if not. + * @param pThread The thread structure. + */ +DECLHIDDEN(bool) rtThreadNativeIsAliveKludge(PRTTHREADINT pThread); +#endif + +#ifdef IN_RING0 +/** + * Called from rtThreadWait when the last thread has completed in order to make + * sure it's all the way out of IPRT before RTR0Term is called. + * + * @param pThread The thread structure. + */ +DECLHIDDEN(void) rtThreadNativeWaitKludge(PRTTHREADINT pThread); +#endif + + +/** + * Sets the priority of the thread according to the thread type + * and current process priority. + * + * The RTTHREADINT::enmType member has not yet been updated and will be updated by + * the caller on a successful return. + * + * @returns iprt status code. + * @param pThread The thread in question. + * @param enmType The thread type. + * @remark Located in sched. + */ +DECLHIDDEN(int) rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType); + +#ifdef IN_RING3 +# ifdef RT_OS_WINDOWS +/** + * Callback for when a native thread is detaching. + * + * It give the Win32/64 backend a chance to terminate alien + * threads properly. + */ +DECLHIDDEN(void) rtThreadNativeDetach(void); + +/** + * Internal function for informing the debugger about a thread. + * @param pThread The thread. May differ from the calling thread. + */ +DECLHIDDEN(void) rtThreadNativeInformDebugger(PRTTHREADINT pThread); +# endif +#endif /* IN_RING3 */ + + +/* thread.cpp */ +DECL_HIDDEN_CALLBACK(int) rtThreadMain(PRTTHREADINT pThread, RTNATIVETHREAD NativeThread, const char *pszThreadName); +DECLHIDDEN(uint32_t) rtThreadRelease(PRTTHREADINT pThread); +DECLHIDDEN(void) rtThreadTerminate(PRTTHREADINT pThread, int rc); +DECLHIDDEN(PRTTHREADINT) rtThreadGetByNative(RTNATIVETHREAD NativeThread); +DECLHIDDEN(PRTTHREADINT) rtThreadGet(RTTHREAD Thread); +DECLHIDDEN(int) rtThreadInit(void); +#ifdef IN_RING3 +DECLHIDDEN(void) rtThreadReInitObtrusive(void); +#endif +DECLHIDDEN(void) rtThreadTerm(void); +DECLHIDDEN(void) rtThreadInsert(PRTTHREADINT pThread, RTNATIVETHREAD NativeThread); +#ifdef IN_RING3 +DECLHIDDEN(int) rtThreadDoSetProcPriority(RTPROCPRIORITY enmPriority); +#endif /* !IN_RING0 */ +#ifdef IPRT_WITH_GENERIC_TLS +DECLHIDDEN(void) rtThreadClearTlsEntry(RTTLS iTls); +DECLHIDDEN(void) rtThreadTlsDestruction(PRTTHREADINT pThread); /* in tls-generic.cpp */ +#endif +#ifdef RT_OS_WINDOWS +DECLHIDDEN(void) rtThreadWinTlsDestruction(void); /* in tls-win.cpp */ +#endif + +/* thread-posix.cpp */ +#ifdef IN_RING3 +# if !defined(RT_OS_WINDOWS) && !defined(RT_OS_OS2) && !defined(RT_OS_DARWIN) +# define RTTHREAD_POSIX_WITH_CREATE_PRIORITY_PROXY +# endif +# ifdef RTTHREAD_POSIX_WITH_CREATE_PRIORITY_PROXY +DECLHIDDEN(bool) rtThreadPosixPriorityProxyStart(void); +DECLHIDDEN(int) rtThreadPosixPriorityProxyCall(PRTTHREADINT pTargetThread, PFNRT pfnFunction, int cArgs, ...); +# endif +#endif + +#ifdef IPRT_INCLUDED_asm_h + +/** + * Gets the thread state. + * + * @returns The thread state. + * @param pThread The thread. + */ +DECLINLINE(RTTHREADSTATE) rtThreadGetState(PRTTHREADINT pThread) +{ + return pThread->enmState; +} + +/** + * Sets the thread state. + * + * @param pThread The thread. + * @param enmNewState The new thread state. + */ +DECLINLINE(void) rtThreadSetState(PRTTHREADINT pThread, RTTHREADSTATE enmNewState) +{ + AssertCompile(sizeof(pThread->enmState) == sizeof(uint32_t)); + ASMAtomicWriteU32((uint32_t volatile *)&pThread->enmState, enmNewState); +} + +#endif + +RT_C_DECLS_END + +#endif /* !IPRT_INCLUDED_INTERNAL_thread_h */ diff --git a/src/VBox/Runtime/include/internal/time.h b/src/VBox/Runtime/include/internal/time.h new file mode 100644 index 00000000..c81ee12e --- /dev/null +++ b/src/VBox/Runtime/include/internal/time.h @@ -0,0 +1,55 @@ +/* $Id: time.h $ */ +/** @file + * IPRT - Internal RTTime header + */ + +/* + * Copyright (C) 2006-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_INTERNAL_time_h +#define IPRT_INCLUDED_INTERNAL_time_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/types.h> + +RT_C_DECLS_BEGIN + +#if defined(IN_RING3) || defined(IN_RC) + +extern DECL_HIDDEN_DATA(uint64_t) g_u64ProgramStartNanoTS; + +#endif + +RT_C_DECLS_END + +#endif /* !IPRT_INCLUDED_INTERNAL_time_h */ |