bump product version to 7.2.5.1
[LibreOffice.git] / bridges / inc / vtablefactory.hxx
blobc169f7c0bfd0dd448b1b5eefc93bf3f3dfc30b49
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #pragma once
22 #include <osl/mutex.hxx>
23 #include <rtl/alloc.h>
24 #include <rtl/ustring.hxx>
25 #include <sal/types.h>
26 #include <typelib/typedescription.hxx>
28 #include <memory>
29 #include <unordered_map>
31 /*See: http://people.redhat.com/drepper/selinux-mem.html*/
32 #if defined(LINUX) || defined(OPENBSD) || defined(FREEBSD) \
33 || defined(NETBSD) || defined(DRAGONFLY) || defined (ANDROID) \
34 || defined(HAIKU)
35 #define USE_DOUBLE_MMAP
36 #endif
38 namespace bridges::cpp_uno::shared {
40 /** Hand out vtable structures for interface type descriptions.
42 class VtableFactory {
43 public:
44 // This structure is not defined in the generic part, but instead has to be
45 // defined individually for each CPP--UNO bridge:
46 /** A vtable slot.
48 struct Slot;
50 /** A raw vtable block.
52 struct Block {
53 /** The start of the raw vtable block.
55 It points to the start of the allocated memory block, whereas the
56 vtable pointer typically points some bytes into the block (e.g.,
57 skipping an RTTI pointer, see mapBlockToVtable). Also, the block
58 contains any generated code snippets, after the vtable itself.
60 void * start;
62 #ifdef USE_DOUBLE_MMAP
63 /** When separately mmapping the block for writing and executing
64 exec points to the same memory as start, except start is used
65 exclusively for writing and exec for executing
67 void * exec;
69 /** File handle for the underlying anonymous file
71 int fd;
72 #endif
74 /** The size of the raw vtable block, in bytes.
76 sal_Size size;
79 /** The vtable structure corresponding to an interface type.
81 struct Vtables {
82 /** The number of blocks/vtables.
84 sal_Int32 count;
86 /** An array of blocks, representing the multiple vtables of a
87 (multiple-inheritance) type.
89 <p>A block is a raw vtable. It points to the start of the allocated
90 memory block, whereas the vtable pointer typically points some bytes
91 into the block (e.g., skipping an RTTI pointer, see
92 mapBlockToVtable). Also, the block contains any generated code
93 snippets, after the vtable itself.</p>
95 std::unique_ptr<Block[]> blocks;
97 Vtables()
98 : count(0)
103 VtableFactory();
105 ~VtableFactory();
107 /** Given an interface type description, return its corresponding vtable
108 structure.
110 const Vtables& getVtables(typelib_InterfaceTypeDescription * type);
112 // This function is not defined in the generic part, but instead has to be
113 // defined individually for each CPP--UNO bridge:
114 /** Given a pointer to a block, turn it into a vtable pointer.
116 static Slot * mapBlockToVtable(void * block);
118 private:
119 class GuardedBlocks;
120 friend class GuardedBlocks;
122 class BaseOffset;
124 VtableFactory(VtableFactory const &) = delete;
125 VtableFactory& operator =(const VtableFactory&) = delete;
127 bool createBlock(Block &block, sal_Int32 slotCount) const;
129 void freeBlock(Block const & block) const;
131 sal_Int32 createVtables(
132 GuardedBlocks & blocks, BaseOffset const & baseOffset,
133 typelib_InterfaceTypeDescription * type, sal_Int32 vtableNumber,
134 typelib_InterfaceTypeDescription * mostDerived, bool includePrimary)
135 const;
137 // This function is not defined in the generic part, but instead has to be
138 // defined individually for each CPP--UNO bridge:
139 /** Calculate the size of a raw vtable block.
141 @param slotCount the number of virtual function slots the returned
142 vtable block shall support (if there are any platform-specific slots,
143 like an RTTI pointer, or a pointer to a destructor, they are not covered
144 by slotCount)
145 @return the size of the raw vtable block, in bytes
147 static std::size_t getBlockSize(sal_Int32 slotCount);
149 // This function is not defined in the generic part, but instead has to be
150 // defined individually for each CPP--UNO bridge:
151 /** Initialize a raw vtable block.
153 @param block the start address of the raw vtable block
154 @param slotCount the number of slots
155 @param vtableNumber zero-based count across all the most derived type's
156 vtables (for vtable's "offset to top" slot)
157 @param type non-null most derived type (for vtable's "typeinfo pointer"
158 slot)
159 @return a pointer past the last vtable slot
161 static Slot * initializeBlock(
162 void * block, sal_Int32 slotCount, sal_Int32 vtableNumber,
163 typelib_InterfaceTypeDescription * type);
165 // This function is not defined in the generic part, but instead has to be
166 // defined individually for each CPP--UNO bridge:
167 /** Fill the vtable slots corresponding to all local (i.e., not inherited)
168 functions of a given interface type (and generate any necessary code
169 snippets for them).
171 @param slots on input, points past the vtable slot to be filled with
172 the last virtual function local to the given type; on output, points to
173 the vtable slot filled with the first virtual function local to the
174 given type
175 @param code points to the start of the area where code snippets can be
176 generated
177 @param writetoexecdiff when the same code area is mapped twice, once for
178 writing for code-generation, and once for code-execution, then this
179 records the offset from a writable address to its executable address
180 @param type the interface type description for which to generate vtable
181 slots
182 @param functionOffset the function offset of the first vtable slot
183 (typically coded into the code snippet for that vtable slot)
184 @param functionCount the number of vtable slots to fill (the number of
185 local functions of the given type, passed in so that it doesn't need to
186 be recomputed)
187 @param vtableOffset the offset of this vtable (needed to adjust the
188 this pointer, typically coded into the code snippets for all the filled
189 vtable slots)
190 @return a pointer to the remaining code snippet area
192 static unsigned char * addLocalFunctions(
193 Slot ** slots, unsigned char * code,
194 #ifdef USE_DOUBLE_MMAP
195 sal_PtrDiff writetoexecdiff,
196 #endif
197 typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
198 sal_Int32 functionCount, sal_Int32 vtableOffset);
200 // This function is not defined in the generic part, but instead has to be
201 // defined individually for each CPP--UNO bridge:
202 /** Flush all the generated code snippets of a vtable, on platforms that
203 require it.
205 @param begin points to the start of the code snippet area
206 @param end points behind the end of the code snippet area
208 static void flushCode(
209 unsigned char const * begin, unsigned char const * end);
211 typedef std::unordered_map< OUString, Vtables > Map;
213 osl::Mutex m_mutex;
214 Map m_map;
216 rtl_arena_type * m_arena;
221 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */