Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #ifndef INCLUDED_BRIDGES_INC_BRIDGES_CPP_UNO_SHARED_VTABLEFACTORY_HXX
21 : #define INCLUDED_BRIDGES_INC_BRIDGES_CPP_UNO_SHARED_VTABLEFACTORY_HXX
22 :
23 : #include "osl/mutex.hxx"
24 : #include "rtl/alloc.h"
25 : #include "rtl/ustring.hxx"
26 : #include "sal/types.h"
27 : #include "typelib/typedescription.hxx"
28 :
29 : #include <unordered_map>
30 :
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 : #define USE_DOUBLE_MMAP
35 : #endif
36 :
37 : namespace bridges { namespace cpp_uno { namespace shared {
38 :
39 : /** Hand out vtable structures for interface type descriptions.
40 : */
41 : class VtableFactory {
42 : public:
43 : // This structure is not defined in the generic part, but instead has to be
44 : // defined individually for each CPP--UNO bridge:
45 : /** A vtable slot.
46 : */
47 : struct Slot;
48 :
49 : /** A raw vtable block.
50 : */
51 : struct Block {
52 : /** The start of the raw vtable block.
53 :
54 : It points to the start of the allocated memory block, whereas the
55 : vtable pointer typically points some bytes into the block (e.g.,
56 : skipping an RTTI pointer, see mapBlockToVtable). Also, the block
57 : contains any generated code snippets, after the vtable itself.
58 : */
59 : void * start;
60 :
61 : #ifdef USE_DOUBLE_MMAP
62 : /** When separately mmapping the block for writing and executing
63 : exec points to the same memory as start, except start is used
64 : exclusively for writing and exec for executing
65 : */
66 : void * exec;
67 :
68 : /** File handle for the underlying anonymous file
69 : */
70 : int fd;
71 : #endif
72 :
73 : /** The size of the raw vtable block, in bytes.
74 : */
75 : sal_Size size;
76 : };
77 :
78 : /** The vtable structure corresponding to an interface type.
79 : */
80 : struct Vtables {
81 : /** The number of blocks/vtables.
82 : */
83 : sal_Int32 count;
84 :
85 : /** An array of blocks, representing the multiple vtables of a
86 : (multiple-inheritance) type.
87 :
88 : <p>A block is a raw vtable. It points to the start of the allocated
89 : memory block, whereas the vtable pointer typically points some bytes
90 : into the block (e.g., skipping an RTTI pointer, see
91 : mapBlockToVtable). Also, the block contains any generated code
92 : snippets, after the vtable itself.</p>
93 : */
94 : Block * blocks;
95 657 : Vtables()
96 : : count(0)
97 657 : , blocks(NULL)
98 : {
99 657 : }
100 : };
101 :
102 : VtableFactory();
103 :
104 : ~VtableFactory();
105 :
106 : /** Given an interface type description, return its corresponding vtable
107 : structure.
108 : */
109 : Vtables getVtables(typelib_InterfaceTypeDescription * type);
110 :
111 : // This function is not defined in the generic part, but instead has to be
112 : // defined individually for each CPP--UNO bridge:
113 : /** Given a pointer to a block, turn it into a vtable pointer.
114 : */
115 : static Slot * mapBlockToVtable(void * block);
116 :
117 : private:
118 : class GuardedBlocks;
119 : friend class GuardedBlocks;
120 :
121 : class BaseOffset;
122 :
123 : VtableFactory(VtableFactory &) SAL_DELETED_FUNCTION;
124 : void operator =(const VtableFactory&) SAL_DELETED_FUNCTION;
125 :
126 : bool createBlock(Block &block, sal_Int32 slotCount) const;
127 :
128 : void freeBlock(Block const & block) const;
129 :
130 : sal_Int32 createVtables(
131 : GuardedBlocks & blocks, BaseOffset const & baseOffset,
132 : typelib_InterfaceTypeDescription * type, sal_Int32 vtableNumber,
133 : typelib_InterfaceTypeDescription * mostDerived, bool includePrimary)
134 : const;
135 :
136 : // This function is not defined in the generic part, but instead has to be
137 : // defined individually for each CPP--UNO bridge:
138 : /** Calculate the size of a raw vtable block.
139 :
140 : @param slotCount the number of virtual function slots the returned
141 : vtable block shall support (if there are any platform-specific slots,
142 : like an RTTI pointer, or a pointer to a destructor, they are not covered
143 : by slotCount)
144 : @return the size of the raw vtable block, in bytes
145 : */
146 : static sal_Size getBlockSize(sal_Int32 slotCount);
147 :
148 : // This function is not defined in the generic part, but instead has to be
149 : // defined individually for each CPP--UNO bridge:
150 : /** Initialize a raw vtable block.
151 :
152 : @param block the start address of the raw vtable block
153 : @param slotCount the number of slots
154 : @param vtableNumber zero-based count across all the most derived type's
155 : vtables (for vtable's "offset to top" slot)
156 : @param type non-null most derived type (for vtable's "typeinfo pointer"
157 : slot)
158 : @return a pointer past the last vtable slot
159 : */
160 : static Slot * initializeBlock(
161 : void * block, sal_Int32 slotCount, sal_Int32 vtableNumber,
162 : typelib_InterfaceTypeDescription * type);
163 :
164 : // This function is not defined in the generic part, but instead has to be
165 : // defined individually for each CPP--UNO bridge:
166 : /** Fill the vtable slots corresponding to all local (i.e., not inherited)
167 : functions of a given interface type (and generate any necessary code
168 : snippets for them).
169 :
170 : @param slots on input, points past the vtable slot to be filled with
171 : the last virtual function local to the given type; on output, points to
172 : the vtable slot filled with the first virtual function local to the
173 : given type
174 : @param code points to the start of the area where code snippets can be
175 : generated
176 : @param writetoexecdiff when the same code area is mmaped twice, once for
177 : writing for code-generation, and once for code-execution, then this
178 : records the offset from a writable address to its executable address
179 : @param type the interface type description for which to generate vtable
180 : slots
181 : @param functionOffset the function offset of the first vtable slot
182 : (typically coded into the code snippet for that vtable slot)
183 : @param functionCount the number of vtable slots to fill (the number of
184 : local functions of the given type, passed in so that it need not be
185 : recomputed)
186 : @param vtableOffset the offset of this vtable (needed to adjust the
187 : this pointer, typically coded into the code snippets for all the filled
188 : vtable slots)
189 : @return a pointer to the remaining code snippet area
190 : */
191 : static unsigned char * addLocalFunctions(
192 : Slot ** slots, unsigned char * code,
193 : #ifdef USE_DOUBLE_MMAP
194 : sal_PtrDiff writetoexecdiff,
195 : #endif
196 : typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
197 : sal_Int32 functionCount, sal_Int32 vtableOffset);
198 :
199 : // This function is not defined in the generic part, but instead has to be
200 : // defined individually for each CPP--UNO bridge:
201 : /** Flush all the generated code snippets of a vtable, on platforms that
202 : require it.
203 :
204 : @param begin points to the start of the code snippet area
205 : @param end points behind the end of the code snippet area
206 : */
207 : static void flushCode(
208 : unsigned char const * begin, unsigned char const * end);
209 :
210 : typedef std::unordered_map< OUString, Vtables, OUStringHash > Map;
211 :
212 : osl::Mutex m_mutex;
213 : Map m_map;
214 :
215 : rtl_arena_type * m_arena;
216 : };
217 :
218 : } } }
219 :
220 : #endif
221 :
222 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|