LCOV - code coverage report
Current view: top level - memory/build - replace_malloc_bridge.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 4 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 1 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
       5             :  * You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #ifndef replace_malloc_bridge_h
       8             : #define replace_malloc_bridge_h
       9             : 
      10             : /*
      11             :  * The replace-malloc bridge allows bidirectional method calls between
      12             :  * a program and the replace-malloc library that has been loaded for it.
      13             :  * In Firefox, this is used to allow method calls between code in libxul
      14             :  * and code in the replace-malloc library, without libxul needing to link
      15             :  * against that library or vice-versa.
      16             :  *
      17             :  * Subsystems can add methods for their own need. Replace-malloc libraries
      18             :  * can decide to implement those methods or not.
      19             :  *
      20             :  * Replace-malloc libraries can provide such a bridge by implementing
      21             :  * a ReplaceMallocBridge-derived class, and a replace_get_bridge function
      22             :  * returning an instance of that class. The default methods in
      23             :  * ReplaceMallocBridge are expected to return values that callers would
      24             :  * understand as "the bridge doesn't implement this method", so that a
      25             :  * replace-malloc library doesn't have to implement all methods.
      26             :  *
      27             :  * The ReplaceMallocBridge class contains definitions for methods for
      28             :  * all replace-malloc libraries. Each library picks the methods it wants
      29             :  * to reply to in its ReplaceMallocBridge-derived class instance.
      30             :  * All methods of ReplaceMallocBridge must be virtual. Similarly,
      31             :  * anything passed as an argument to those methods must be plain data, or
      32             :  * an instance of a class with only virtual methods.
      33             :  *
      34             :  * Binary compatibility is expected to be maintained, such that a newer
      35             :  * Firefox can be used with an old replace-malloc library, or an old
      36             :  * Firefox can be used with a newer replace-malloc library. As such, only
      37             :  * new virtual methods should be added to ReplaceMallocBridge, and
      38             :  * each change should have a corresponding bump of the mVersion value.
      39             :  * At the same time, each virtual method should have a corresponding
      40             :  * wrapper calling the virtual method on the instance from
      41             :  * ReplaceMallocBridge::Get(), giving it the version the virtual method
      42             :  * was added.
      43             :  *
      44             :  * Parts that are not relevant to the replace-malloc library end of the
      45             :  * bridge are hidden when REPLACE_MALLOC_IMPL is not defined, which is
      46             :  * the case when including replace_malloc.h.
      47             :  */
      48             : 
      49             : struct ReplaceMallocBridge;
      50             : 
      51             : #include "mozilla/Types.h"
      52             : 
      53             : MOZ_BEGIN_EXTERN_C
      54             : 
      55             : #ifndef REPLACE_MALLOC_IMPL
      56             : /* Returns the replace-malloc bridge if there is one to be returned. */
      57             : MFBT_API ReplaceMallocBridge* get_bridge();
      58             : #endif
      59             : 
      60             : /* Table of malloc functions.
      61             :  *   e.g. void* (*malloc)(size_t), etc.
      62             :  */
      63             : #define MALLOC_DECL(name, return_type, ...) \
      64             :   typedef return_type(name ## _impl_t)(__VA_ARGS__);
      65             : 
      66             : #include "malloc_decls.h"
      67             : 
      68             : #define MALLOC_DECL(name, return_type, ...) \
      69             :   name ## _impl_t * name;
      70             : 
      71             : typedef struct {
      72             : #include "malloc_decls.h"
      73             : } malloc_table_t;
      74             : 
      75             : 
      76             : /* Table of malloc hook functions.
      77             :  * Those functions are called with the arguments and results of malloc
      78             :  * functions after they are called.
      79             :  *   e.g. void* (*malloc_hook)(void*, size_t), etc.
      80             :  * They can either return the result they're given, or alter it before
      81             :  * returning it.
      82             :  * The hooks corresponding to functions, like free(void*), that return no
      83             :  * value, don't take an extra argument.
      84             :  * The table must at least contain a pointer for malloc_hook and free_hook
      85             :  * functions. They will be used as fallback if no pointer is given for
      86             :  * other allocation functions, like calloc_hook.
      87             :  */
      88             : #define MALLOC_DECL(name, return_type, ...) \
      89             :   return_type (*name ## _hook)(return_type, __VA_ARGS__);
      90             : #define MALLOC_DECL_VOID(name, ...) \
      91             :   void (*name ## _hook)(__VA_ARGS__);
      92             : 
      93             : typedef struct {
      94             : #include "malloc_decls.h"
      95             :   /* Like free_hook, but called before realloc_hook. free_hook is called
      96             :    * instead of not given. */
      97             :   void (*realloc_hook_before)(void* aPtr);
      98             : } malloc_hook_table_t;
      99             : 
     100             : MOZ_END_EXTERN_C
     101             : 
     102             : #ifdef __cplusplus
     103             : 
     104             : namespace mozilla {
     105             : namespace dmd {
     106             : struct DMDFuncs;
     107             : } // namespace dmd
     108             : 
     109             : /* Callbacks to register debug file handles for Poison IO interpose.
     110             :  * See Mozilla(|Un)RegisterDebugHandle in xpcom/build/PoisonIOInterposer.h */
     111             : struct DebugFdRegistry
     112             : {
     113             :   virtual void RegisterHandle(intptr_t aFd);
     114             : 
     115             :   virtual void UnRegisterHandle(intptr_t aFd);
     116             : };
     117             : 
     118             : } // namespace mozilla
     119             : 
     120             : struct ReplaceMallocBridge
     121             : {
     122             :   ReplaceMallocBridge() : mVersion(3) {}
     123             : 
     124             :   /* This method was added in version 1 of the bridge. */
     125             :   virtual mozilla::dmd::DMDFuncs* GetDMDFuncs() { return nullptr; }
     126             : 
     127             :   /* Send a DebugFdRegistry instance to the replace-malloc library so that
     128             :    * it can register/unregister file descriptors whenever needed. The
     129             :    * instance is valid until the process dies.
     130             :    * This method was added in version 2 of the bridge. */
     131             :   virtual void InitDebugFd(mozilla::DebugFdRegistry&) {}
     132             : 
     133             :   /* Register a list of malloc functions and hook functions to the
     134             :    * replace-malloc library so that it can choose to dispatch to them
     135             :    * when needed. The details of what is dispatched when is left to the
     136             :    * replace-malloc library.
     137             :    * Passing a nullptr for either table will unregister a previously
     138             :    * registered table under the same name.
     139             :    * Returns nullptr if registration failed.
     140             :    * If registration succeeded, a table of "pure" malloc functions is
     141             :    * returned. Those "pure" malloc functions won't call hooks.
     142             :    * /!\ Do not rely on registration/unregistration to be instantaneous.
     143             :    * Functions from a previously registered table may still be called for
     144             :    * a brief time after RegisterHook returns.
     145             :    * This method was added in version 3 of the bridge. */
     146             :   virtual const malloc_table_t*
     147             :   RegisterHook(const char* aName, const malloc_table_t* aTable,
     148             :                const malloc_hook_table_t* aHookTable) { return nullptr; }
     149             : 
     150             : #ifndef REPLACE_MALLOC_IMPL
     151             :   /* Returns the replace-malloc bridge if its version is at least the
     152             :    * requested one. */
     153           0 :   static ReplaceMallocBridge* Get(int aMinimumVersion) {
     154           0 :     static ReplaceMallocBridge* sSingleton = get_bridge();
     155           0 :     return (sSingleton && sSingleton->mVersion >= aMinimumVersion)
     156           0 :       ? sSingleton : nullptr;
     157             :   }
     158             : #endif
     159             : 
     160             : protected:
     161             :   const int mVersion;
     162             : };
     163             : 
     164             : #ifndef REPLACE_MALLOC_IMPL
     165             : /* Class containing wrappers for calls to ReplaceMallocBridge methods.
     166             :  * Those wrappers need to be static methods in a class because compilers
     167             :  * complain about unused static global functions, and linkers complain
     168             :  * about multiple definitions of non-static global functions.
     169             :  * Using a separate class from ReplaceMallocBridge allows the function
     170             :  * names to be identical. */
     171             : struct ReplaceMalloc
     172             : {
     173             :   /* Don't call this method from performance critical code. Use
     174             :    * mozilla::dmd::DMDFuncs::Get() instead, it has less overhead. */
     175             :   static mozilla::dmd::DMDFuncs* GetDMDFuncs()
     176             :   {
     177             :     auto singleton = ReplaceMallocBridge::Get(/* minimumVersion */ 1);
     178             :     return singleton ? singleton->GetDMDFuncs() : nullptr;
     179             :   }
     180             : 
     181             :   static void InitDebugFd(mozilla::DebugFdRegistry& aRegistry)
     182             :   {
     183             :     auto singleton = ReplaceMallocBridge::Get(/* minimumVersion */ 2);
     184             :     if (singleton) {
     185             :       singleton->InitDebugFd(aRegistry);
     186             :     }
     187             :   }
     188             : 
     189             :   static const malloc_table_t*
     190             :   RegisterHook(const char* aName, const malloc_table_t* aTable,
     191             :                const malloc_hook_table_t* aHookTable)
     192             :   {
     193             :     auto singleton = ReplaceMallocBridge::Get(/* minimumVersion */ 3);
     194             :     return singleton ? singleton->RegisterHook(aName, aTable, aHookTable)
     195             :                      : nullptr;
     196             :   }
     197             : };
     198             : #endif
     199             : 
     200             : #endif /* __cplusplus */
     201             : 
     202             : #endif /* replace_malloc_bridge_h */

Generated by: LCOV version 1.13