1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #ifndef INCLUDED_BRIDGES_CPP_UNO_SHARED_VTABLEFACTORY_HXX 25 #define INCLUDED_BRIDGES_CPP_UNO_SHARED_VTABLEFACTORY_HXX 26 27 #include "osl/mutex.hxx" 28 #include "rtl/alloc.h" 29 #include "rtl/ustring.hxx" 30 #include "sal/types.h" 31 #include "typelib/typedescription.hxx" 32 33 #include <hash_map> 34 35 /*See: http://people.redhat.com/drepper/selinux-mem.html*/ 36 #if defined (LINUX) || defined (FREEBSD) 37 #define USE_DOUBLE_MMAP 38 #endif 39 40 namespace bridges { namespace cpp_uno { namespace shared { 41 42 /** Hand out vtable structures for interface type descriptions. 43 */ 44 class VtableFactory { 45 public: 46 // This structure is not defined in the generic part, but instead has to be 47 // defined individually for each CPP--UNO bridge: 48 /** A vtable slot. 49 */ 50 struct Slot; 51 52 /** A raw vtable block. 53 */ 54 struct Block { 55 /** The start of the raw vtable block. 56 57 It points to the start of the allocated memory block, whereas the 58 vtable pointer typically points some bytes into the block (e.g., 59 skipping an RTTI pointer, see mapBlockToVtable). Also, the block 60 contains any generated code snippets, after the vtable itself. 61 */ 62 void * start; 63 64 #ifdef USE_DOUBLE_MMAP 65 /** When separately mmapping the block for writing and executing 66 exec points to the same memory as start, except start is used 67 exclusively for writing and exec for executing 68 */ 69 void * exec; 70 71 /** File handle for the underlying anonymous file 72 */ 73 int fd; 74 #endif 75 76 /** The size of the raw vtable block, in bytes. 77 */ 78 sal_Size size; 79 }; 80 81 /** The vtable structure corresponding to an interface type. 82 */ 83 struct Vtables { 84 /** The number of blocks/vtables. 85 */ 86 sal_Int32 count; 87 88 /** An array of blocks, representing the multiple vtables of a 89 (multiple-inheritance) type. 90 91 <p>A block is a raw vtable. It points to the start of the allocated 92 memory block, whereas the vtable pointer typically points some bytes 93 into the block (e.g., skipping an RTTI pointer, see 94 mapBlockToVtable). Also, the block contains any generated code 95 snippets, after the vtable itself.</p> 96 */ 97 Block * blocks; 98 }; 99 100 VtableFactory(); 101 102 ~VtableFactory(); 103 104 /** Given an interface type description, return its corresponding vtable 105 structure. 106 */ 107 Vtables getVtables(typelib_InterfaceTypeDescription * type); 108 109 // This function is not defined in the generic part, but instead has to be 110 // defined individually for each CPP--UNO bridge: 111 /** Given a pointer to a block, turn it into a vtable pointer. 112 */ 113 static Slot * mapBlockToVtable(void * block); 114 115 private: 116 class GuardedBlocks; 117 friend class GuardedBlocks; 118 119 class BaseOffset; 120 121 VtableFactory(VtableFactory &); // not implemented 122 void operator =(VtableFactory); // not implemented 123 124 bool createBlock(Block &block, sal_Int32 slotCount) const; 125 126 void freeBlock(Block const & block) const; 127 128 void createVtables( 129 GuardedBlocks & blocks, BaseOffset const & baseOffset, 130 typelib_InterfaceTypeDescription * type, bool includePrimary) const; 131 132 // This function is not defined in the generic part, but instead has to be 133 // defined individually for each CPP--UNO bridge: 134 /** Calculate the size of a raw vtable block. 135 136 @param slotCount the number of virtual function slots the returned 137 vtable block shall support (if there are any platform-specific slots, 138 like an RTTI pointer, or a pointer to a destructor, they are not covered 139 by slotCount) 140 @return the size of the raw vtable block, in bytes 141 */ 142 static sal_Size getBlockSize(sal_Int32 slotCount); 143 144 // This function is not defined in the generic part, but instead has to be 145 // defined individually for each CPP--UNO bridge: 146 /** Initialize a raw vtable block. 147 148 @param block the start address of the raw vtable block 149 @param slotCount the number of slots 150 @return a pointer past the last vtable slot 151 */ 152 static Slot * initializeBlock(void * block, sal_Int32 slotCount); 153 154 // This function is not defined in the generic part, but instead has to be 155 // defined individually for each CPP--UNO bridge: 156 /** Fill the vtable slots corresponding to all local (i.e., not inherited) 157 functions of a given interface type (and generate any necessary code 158 snippets for them). 159 160 @param slots on input, points past the vtable slot to be filled with 161 the last virtual function local to the given type; on output, points to 162 the vtable slot filled with the first virtual function local to the 163 given type 164 @param code points to the start of the area where code snippets can be 165 generated 166 @param writetoexecdiff when the same code area is mmaped twice, once for 167 writing for code-generation, and once for code-execution, then this 168 records the offset from a writable address to its executable address 169 @param type the interface type description for which to generate vtable 170 slots 171 @param functionOffset the function offset of the first vtable slot 172 (typically coded into the code snippet for that vtable slot) 173 @param functionCount the number of vtable slots to fill (the number of 174 local functions of the given type, passed in so that it need not be 175 recomputed) 176 @param vtableOffset the offset of this vtable (needed to adjust the 177 this pointer, typically coded into the code snippets for all the filled 178 vtable slots) 179 @return a pointer to the remaining code snippet area 180 */ 181 static unsigned char * addLocalFunctions( 182 Slot ** slots, unsigned char * code, 183 #ifdef USE_DOUBLE_MMAP 184 sal_PtrDiff writetoexecdiff, 185 #endif 186 typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset, 187 sal_Int32 functionCount, sal_Int32 vtableOffset); 188 189 // This function is not defined in the generic part, but instead has to be 190 // defined individually for each CPP--UNO bridge: 191 /** Flush all the generated code snippets of a vtable, on platforms that 192 require it. 193 194 @param begin points to the start of the code snippet area 195 @param end points behind the end of the code snippet area 196 */ 197 static void flushCode( 198 unsigned char const * begin, unsigned char const * end); 199 200 typedef std::hash_map< rtl::OUString, Vtables, rtl::OUStringHash > Map; 201 202 osl::Mutex m_mutex; 203 Map m_map; 204 205 rtl_arena_type * m_arena; 206 }; 207 208 } } } 209 210 #endif 211