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 <boost/unordered_map.hpp>
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 : || (defined(MACOSX) && defined(__LP64__))
35 : #define USE_DOUBLE_MMAP
36 : #endif
37 :
38 : namespace bridges { namespace cpp_uno { namespace shared {
39 :
40 : /** Hand out vtable structures for interface type descriptions.
41 : */
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.
47 : */
48 : struct Slot;
49 :
50 : /** A raw vtable block.
51 : */
52 : struct Block {
53 : /** The start of the raw vtable block.
54 :
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.
59 : */
60 : void * start;
61 :
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
66 : */
67 : void * exec;
68 :
69 : /** File handle for the underlying anonymous file
70 : */
71 : int fd;
72 : #endif
73 :
74 : /** The size of the raw vtable block, in bytes.
75 : */
76 : sal_Size size;
77 : };
78 :
79 : /** The vtable structure corresponding to an interface type.
80 : */
81 : struct Vtables {
82 : /** The number of blocks/vtables.
83 : */
84 : sal_Int32 count;
85 :
86 : /** An array of blocks, representing the multiple vtables of a
87 : (multiple-inheritance) type.
88 :
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>
94 : */
95 : Block * blocks;
96 871 : Vtables()
97 : : count(0)
98 871 : , blocks(NULL)
99 : {
100 871 : }
101 : };
102 :
103 : VtableFactory();
104 :
105 : ~VtableFactory();
106 :
107 : /** Given an interface type description, return its corresponding vtable
108 : structure.
109 : */
110 : Vtables getVtables(typelib_InterfaceTypeDescription * type);
111 :
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.
115 : */
116 : static Slot * mapBlockToVtable(void * block);
117 :
118 : private:
119 : class GuardedBlocks;
120 : friend class GuardedBlocks;
121 :
122 : class BaseOffset;
123 :
124 : VtableFactory(VtableFactory &); // not implemented
125 : void operator =(const VtableFactory&); // not implemented
126 :
127 : bool createBlock(Block &block, sal_Int32 slotCount) const;
128 :
129 : void freeBlock(Block const & block) const;
130 :
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;
136 :
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.
140 :
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
146 : */
147 : static sal_Size getBlockSize(sal_Int32 slotCount);
148 :
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.
152 :
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
160 : */
161 : static Slot * initializeBlock(
162 : void * block, sal_Int32 slotCount, sal_Int32 vtableNumber,
163 : typelib_InterfaceTypeDescription * type);
164 :
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).
170 :
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 mmaped 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 need not be
186 : 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
191 : */
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);
199 :
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.
204 :
205 : @param begin points to the start of the code snippet area
206 : @param end points behind the end of the code snippet area
207 : */
208 : static void flushCode(
209 : unsigned char const * begin, unsigned char const * end);
210 :
211 : typedef boost::unordered_map< OUString, Vtables, OUStringHash > Map;
212 :
213 : osl::Mutex m_mutex;
214 : Map m_map;
215 :
216 : rtl_arena_type * m_arena;
217 : };
218 :
219 : } } }
220 :
221 : #endif
222 :
223 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|