Index: inc/bridges/cpp_uno/shared/vtablefactory.hxx
===================================================================
RCS file: /cvs/udk/bridges/inc/bridges/cpp_uno/shared/vtablefactory.hxx,v
retrieving revision 1.5
diff -u -r1.5 vtablefactory.hxx
--- bridges/inc/bridges/cpp_uno/shared/vtablefactory.hxx	2 May 2006 11:59:11 -0000	1.5
+++ bridges/inc/bridges/cpp_uno/shared/vtablefactory.hxx	17 May 2006 10:57:45 -0000
@@ -60,11 +60,21 @@
             skipping an RTTI pointer, see mapBlockToVtable).  Also, the block
             contains any generated code snippets, after the vtable itself.
          */
-        void * start;
+	int fd;
+        void * writep;
+        void * execp;
+	int * ref;
 
         /** The size of the raw vtable block, in bytes.
          */
         sal_Size size;
+	Block(sal_Size nSize);
+	Block(const Block &rOther);
+	~Block();
+	Block();
+	Block& operator=(const Block& rOther);
+	void swapwriteandexec();
+	void release();
     };
 
     /** The vtable structure corresponding to an interface type.
@@ -110,8 +120,6 @@
     VtableFactory(VtableFactory &); // not implemented
     void operator =(VtableFactory); // not implemented
 
-    void freeBlock(Block const & block) const;
-
     void createVtables(
         GuardedBlocks & blocks, BaseOffset const & baseOffset,
         typelib_InterfaceTypeDescription * type, bool includePrimary) const;
@@ -162,7 +170,7 @@
         @return  a pointer to the remaining code snippet area
      */
     static unsigned char * addLocalFunctions(
-        void ** slots, unsigned char * code,
+        void ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
         typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
         sal_Int32 functionCount, sal_Int32 vtableOffset);
 
@@ -181,8 +189,6 @@
 
     osl::Mutex m_mutex;
     Map m_map;
-
-    rtl_arena_type * m_arena;
 };
 
 } } }
Index: source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx
===================================================================
RCS file: /cvs/udk/bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx,v
retrieving revision 1.10
diff -u -r1.10 cpp2uno.cxx
--- bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx	2 May 2006 12:01:33 -0000	1.10
+++ bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx	17 May 2006 10:57:47 -0000
@@ -361,7 +361,7 @@
 int const codeSnippetSize = 16;
 
 unsigned char * codeSnippet(
-    unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset,
+    unsigned char * code, sal_PtrDiff writetoexecdiff, sal_Int32 functionIndex, sal_Int32 vtableOffset,
     typelib_TypeClass returnTypeClass)
 {
     if (!bridges::cpp_uno::shared::isSimpleType(returnTypeClass)) {
@@ -407,7 +407,7 @@
     // jmp privateSnippetExecutor:
     *p++ = 0xE9;
     *reinterpret_cast< sal_Int32 * >(p)
-        = ((unsigned char *) exec) - p - sizeof (sal_Int32);
+        = ((unsigned char *) exec) - p - sizeof (sal_Int32) - writetoexecdiff;
     p += sizeof (sal_Int32);
     OSL_ASSERT(p - code <= codeSnippetSize);
     return code + codeSnippetSize;
@@ -434,7 +434,7 @@
 }
 
 unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
-    void ** slots, unsigned char * code,
+    void ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
     typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
     sal_Int32 functionCount, sal_Int32 vtableOffset)
 {
@@ -445,9 +445,9 @@
         switch (member->eTypeClass) {
         case typelib_TypeClass_INTERFACE_ATTRIBUTE:
             // Getter:
-            *slots++ = code;
+            *slots++ = code + writetoexecdiff;
             code = codeSnippet(
-                code, functionOffset++, vtableOffset,
+                code, writetoexecdiff, functionOffset++, vtableOffset,
                 reinterpret_cast< typelib_InterfaceAttributeTypeDescription * >(
                     member)->pAttributeTypeRef->eTypeClass);
             // Setter:
@@ -455,17 +455,17 @@
                 typelib_InterfaceAttributeTypeDescription * >(
                     member)->bReadOnly)
             {
-                *slots++ = code;
+                *slots++ = code + writetoexecdiff;
                 code = codeSnippet(
-                    code, functionOffset++, vtableOffset,
+                    code, writetoexecdiff, functionOffset++, vtableOffset,
                     typelib_TypeClass_VOID);
             }
             break;
 
         case typelib_TypeClass_INTERFACE_METHOD:
-            *slots++ = code;
+            *slots++ = code + writetoexecdiff;
             code = codeSnippet(
-                code, functionOffset++, vtableOffset,
+                code, writetoexecdiff, functionOffset++, vtableOffset,
                 reinterpret_cast< typelib_InterfaceMethodTypeDescription * >(
                     member)->pReturnTypeRef->eTypeClass);
             break;
Index: source/cpp_uno/gcc3_linux_powerpc/cpp2uno.cxx
===================================================================
RCS file: /cvs/udk/bridges/source/cpp_uno/gcc3_linux_powerpc/cpp2uno.cxx,v
retrieving revision 1.8
diff -u -r1.8 cpp2uno.cxx
--- bridges/source/cpp_uno/gcc3_linux_powerpc/cpp2uno.cxx	2 May 2006 12:02:15 -0000	1.8
+++ bridges/source/cpp_uno/gcc3_linux_powerpc/cpp2uno.cxx	17 May 2006 10:57:47 -0000
@@ -676,7 +676,7 @@
 }
 
 unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
-    void ** slots, unsigned char * code,
+    void ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
     typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
     sal_Int32 functionCount, sal_Int32 vtableOffset)
 {
@@ -692,7 +692,7 @@
         switch (member->eTypeClass) {
         case typelib_TypeClass_INTERFACE_ATTRIBUTE:
             // Getter:
-            *slots++ = code;
+            *slots++ = code + writetoexecdiff;
             code = codeSnippet(
                 code, functionOffset++, vtableOffset,
                 bridges::cpp_uno::shared::isSimpleType(
@@ -705,13 +705,13 @@
                 typelib_InterfaceAttributeTypeDescription * >(
                     member)->bReadOnly)
             {
-                *slots++ = code;
+                *slots++ = code + writetoexecdiff;
                 code = codeSnippet(code, functionOffset++, vtableOffset, true);
             }
             break;
 
         case typelib_TypeClass_INTERFACE_METHOD:
-            *slots++ = code;
+            *slots++ = code + writetoexecdiff;
             code = codeSnippet(
                 code, functionOffset++, vtableOffset,
                 bridges::cpp_uno::shared::isSimpleType(
Index: source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx
===================================================================
RCS file: /cvs/udk/bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx,v
retrieving revision 1.5
diff -u -r1.5 cpp2uno.cxx
--- bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx	2 May 2006 12:03:36 -0000	1.5
+++ bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx	17 May 2006 10:57:48 -0000
@@ -487,7 +487,7 @@
 //==================================================================================================
 
 unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
-	void ** slots, unsigned char * code,
+	void ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff, 
 	typelib_InterfaceTypeDescription const * type, sal_Int32 nFunctionOffset,
 	sal_Int32 functionCount, sal_Int32 nVtableOffset )
 {
@@ -504,14 +504,14 @@
 				reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>( pTD );
 
 			// get method
-			*slots++ = code;
+			*slots++ = code + writetoexecdiff;
 			code = codeSnippet( code, nFunctionOffset++, nVtableOffset,
 								x86_64::return_in_hidden_param( pAttrTD->pAttributeTypeRef ) );
 
 			if ( ! pAttrTD->bReadOnly )
 			{
 				// set method
-				*slots++ = code;
+				*slots++ = code + writetoexecdiff;
 				code = codeSnippet( code, nFunctionOffset++, nVtableOffset, false );
 			}
 		}
@@ -520,7 +520,7 @@
 			typelib_InterfaceMethodTypeDescription *pMethodTD =
 				reinterpret_cast<typelib_InterfaceMethodTypeDescription *>( pTD );
 			
-			*slots++ = code;
+			*slots++ = code + writetoexecdiff;
 			code = codeSnippet( code, nFunctionOffset++, nVtableOffset,
 								x86_64::return_in_hidden_param( pMethodTD->pReturnTypeRef ) );
 		}
Index: source/cpp_uno/shared/cppinterfaceproxy.cxx
===================================================================
RCS file: /cvs/udk/bridges/source/cpp_uno/shared/cppinterfaceproxy.cxx,v
retrieving revision 1.4
diff -u -r1.4 cppinterfaceproxy.cxx
--- bridges/source/cpp_uno/shared/cppinterfaceproxy.cxx	2 May 2006 12:07:01 -0000	1.4
+++ bridges/source/cpp_uno/shared/cppinterfaceproxy.cxx	17 May 2006 10:57:48 -0000
@@ -89,7 +89,7 @@
         pMemory.release());
     for (sal_Int32 i = 0; i < aVtables.count; ++i) {
         pProxy->vtables[i] = VtableFactory::mapBlockToVtable(
-            aVtables.blocks[i].start);
+            aVtables.blocks[i].writep);
     }
     return castProxyToInterface(pProxy);
 }
Index: source/cpp_uno/shared/vtablefactory.cxx
===================================================================
RCS file: /cvs/udk/bridges/source/cpp_uno/shared/vtablefactory.cxx,v
retrieving revision 1.5
diff -u -r1.5 vtablefactory.cxx
--- bridges/source/cpp_uno/shared/vtablefactory.cxx	2 May 2006 12:07:18 -0000	1.5
+++ bridges/source/cpp_uno/shared/vtablefactory.cxx	17 May 2006 10:57:48 -0000
@@ -41,6 +41,9 @@
 
 #include "osl/diagnose.h"
 #include "osl/mutex.hxx"
+#include "osl/thread.h"
+#include "osl/security.hxx"
+#include "osl/file.hxx"
 #include "rtl/alloc.h"
 #include "rtl/ustring.hxx"
 #include "sal/types.h"
@@ -53,6 +56,7 @@
 #if defined SAL_UNX
 #include <unistd.h>
 #include <sys/mman.h>
+#include <stdio.h>
 #elif defined SAL_W32
 #define WIN32_LEAN_AND_MEAN
 #pragma warning(push,1) // disable warnings within system headers
@@ -64,9 +68,12 @@
 
 using bridges::cpp_uno::shared::VtableFactory;
 
-namespace {
+VtableFactory::Block::Block() : fd(-1), writep(0), execp(0), ref(0), size(0)
+{
+}
 
-extern "C" void * SAL_CALL allocExec(rtl_arena_type *, sal_Size * size) {
+VtableFactory::Block::Block(sal_Size nSize) : fd(-1), writep(0), execp(0), ref(0), size(0)
+{
     sal_Size pagesize;
 #if defined SAL_UNX
 #if defined FREEBSD || defined NETBSD
@@ -79,40 +86,112 @@
     GetSystemInfo(&info);
     pagesize = info.dwPageSize;
 #endif
-    sal_Size n = (*size + (pagesize - 1)) & ~(pagesize - 1);
-    void * p;
+    sal_Size n = (nSize + (pagesize - 1)) & ~(pagesize - 1);
 #if defined SAL_UNX
-    p = mmap(
-        0, n, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1,
-        0);
-    if (p == MAP_FAILED) {
-        p = 0;
-    }
-	else if (mprotect (static_cast<char*>(p), n, PROT_READ | PROT_WRITE | PROT_EXEC) == -1)
-	{
-		munmap (static_cast<char*>(p), n);
-		p = 0;
-	}
+    osl::Security aSecurity;
+    rtl::OUString strDirectory;
+    rtl::OUString strURLDirectory;
+    if (aSecurity.getHomeDir(strURLDirectory))
+        osl::File::getSystemPathFromFileURL(strURLDirectory, strDirectory);
+
+    for (int i = strDirectory.getLength() == 0 ? 1 : 0; i < 2; ++i)
+    {
+        if (!strDirectory.getLength())
+            strDirectory = rtl::OUString::createFromAscii("/tmp");
+
+        strDirectory += rtl::OUString::createFromAscii("/.execoooXXXXXX");
+        rtl::OString aTmpName = rtl::OUStringToOString(strDirectory, osl_getThreadTextEncoding());
+        char *tmpfname = new char[aTmpName.getLength()+1];
+        strncpy(tmpfname, aTmpName.getStr(), aTmpName.getLength()+1);
+        if ((fd = mkstemp(tmpfname)) == -1)
+          perror("creation of executable memory area failed");
+        if (fd == -1)
+        {
+            delete[] tmpfname;
+            break;
+        }
+        unlink(tmpfname);
+        delete[] tmpfname;
+        ftruncate(fd, nSize);
+        writep = mmap(NULL, n, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+        if (writep == MAP_FAILED) {
+            writep = 0;
+        }
+        execp = mmap(NULL, n, PROT_READ | PROT_EXEC, MAP_SHARED, fd, 0);
+        if (execp == MAP_FAILED) {
+           execp = 0;
+        }
+
+    	if (writep && execp && fd != -1)
+            break;
+
+        if (writep) munmap(writep, size);
+	writep = 0;
+        if (execp) munmap(execp, size);
+	execp = 0;
+        if (fd != -1) close(fd);
+	fd = -1;
+        strDirectory = rtl::OUString();
+    }
 #elif defined SAL_W32
     p = VirtualAlloc(0, n, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
 #endif
-    if (p != 0) {
-        *size = n;
+    if (writep || execp || fd != -1) {
+        size = n;
+      ref = new int(1);
+    }
+    if (!writep || !execp || fd == -1)
+    {
+	fprintf(stderr, "FATAL ERROR, could not mmap a file for executable memory either in home dir or in /tmp\n");
+	fprintf(stderr, "Cannot continue, perhaps examine your mount options for those directories, or selinux\n");
+	exit(-1);
     }
-    return p;
 }
 
-extern "C" void SAL_CALL freeExec(
-    rtl_arena_type *, void * address, sal_Size size)
+void VtableFactory::Block::release()
 {
+    if (ref)
+    {
+        (*ref)--;
+        if (*ref == 0)
+        {
 #if defined SAL_UNX
-    munmap(static_cast< char * >(address), size);
+            if (writep) munmap(writep, size);
+            if (execp) munmap(execp, size);
+            if (fd != -1) close(fd);
 #elif defined SAL_W32
-    (void) size; // unused
-    VirtualFree(address, 0, MEM_RELEASE);
+            VirtualFree(start, 0, MEM_RELEASE);
 #endif
+          delete ref;
+        }
+    }
 }
 
+VtableFactory::Block::~Block()
+{
+    release();
+}
+
+VtableFactory::Block::Block(const Block& rOther) : fd(rOther.fd), writep(rOther.writep), execp(rOther.execp), ref(rOther.ref), size(rOther.size)
+{
+    if (ref) (*ref)++;
+}
+
+VtableFactory::Block& VtableFactory::Block::operator=(const VtableFactory::Block& rOther)
+{
+    release();
+    fd = rOther.fd;
+    writep = rOther.writep;
+    execp = rOther.execp;
+    size = rOther.size;
+    ref = rOther.ref;
+    if (ref) (*ref)++;
+    return *this;
+}
+
+void VtableFactory::Block::swapwriteandexec()
+{
+    ::std::swap(writep, execp);
 }
 
 class VtableFactory::GuardedBlocks: public std::vector< Block > {
@@ -133,11 +213,6 @@
 };
 
 VtableFactory::GuardedBlocks::~GuardedBlocks() {
-    if (m_guarded) {
-        for (iterator i(begin()); i != end(); ++i) {
-            m_factory.freeBlock(*i);
-        }
-    }
 }
 
 class VtableFactory::BaseOffset {
@@ -172,28 +247,17 @@
     return offset;
 }
 
-VtableFactory::VtableFactory(): m_arena(
-    rtl_arena_create(
-        "bridges::cpp_uno::shared::VtableFactory",
-        sizeof (void *), // to satisfy alignment requirements
-        0, reinterpret_cast< rtl_arena_type * >(-1), allocExec, freeExec, 0))
+VtableFactory::VtableFactory()
 {
-    if (m_arena == 0) {
-        throw std::bad_alloc();
-    }
 }
 
 VtableFactory::~VtableFactory() {
     {
         osl::MutexGuard guard(m_mutex);
         for (Map::iterator i(m_map.begin()); i != m_map.end(); ++i) {
-            for (sal_Int32 j = 0; j < i->second.count; ++j) {
-                freeBlock(i->second.blocks[j]);
-            }
             delete[] i->second.blocks;
         }
     }
-    rtl_arena_destroy(m_arena);
 }
 
 VtableFactory::Vtables VtableFactory::getVtables(
@@ -221,10 +285,6 @@
     return i->second;
 }
 
-void VtableFactory::freeBlock(Block const & block) const {
-    rtl_arena_free(m_arena, block.start, block.size);
-}
-
 void VtableFactory::createVtables(
     GuardedBlocks & blocks, BaseOffset const & baseOffset,
     typelib_InterfaceTypeDescription * type, bool includePrimary) const
@@ -232,17 +292,16 @@
     if (includePrimary) {
         sal_Int32 slotCount
             = bridges::cpp_uno::shared::getPrimaryFunctions(type);
-        Block block;
-        block.size = getBlockSize(slotCount);
-        block.start = rtl_arena_alloc(m_arena, &block.size);
-        if (block.start == 0) {
+        Block block(getBlockSize(slotCount));
+        if (block.writep == 0 || block.execp == 0) {
             throw std::bad_alloc();
         }
         try {
-            void ** slots = initializeBlock(block.start) + slotCount;
+            void ** slots = initializeBlock(block.writep) + slotCount;
             unsigned char * codeBegin =
                 reinterpret_cast< unsigned char * >(slots);
             unsigned char * code = codeBegin;
+	    sal_PtrDiff writetoexecdiff = sal_IntPtr(block.execp) - sal_IntPtr(block.writep);
             sal_Int32 vtableOffset = blocks.size() * sizeof (void **);
             for (typelib_InterfaceTypeDescription const * type2 = type;
                  type2 != 0; type2 = type2->pBaseTypeDescription)
@@ -251,14 +310,14 @@
                     = bridges::cpp_uno::shared::getLocalFunctions(type2);
                 slots -= functionCount;
                 code = addLocalFunctions(
-                    slots, code, type2,
+                    slots, code, writetoexecdiff, type2,
                     baseOffset.getFunctionOffset(type2->aBase.pTypeName),
                     functionCount, vtableOffset);
             }
             flushCode(codeBegin, code);
+	    block.swapwriteandexec();
             blocks.push_back(block);
         } catch (...) {
-            freeBlock(block);
             throw;
         }
     }
Index: source/cpp_uno/gcc3_linux_sparc/cpp2uno.cxx
===================================================================
RCS file: /cvs/udk/bridges/source/cpp_uno/gcc3_linux_sparc/cpp2uno.cxx,v
retrieving revision 1.12
diff -u -r1.12 cpp2uno.cxx
--- bridges/source/cpp_uno/gcc3_linux_sparc/cpp2uno.cxx	22 Nov 2006 11:07:20 -0000	1.12
+++ bridges/source/cpp_uno/gcc3_linux_sparc/cpp2uno.cxx	5 Jun 2007 12:38:03 -0000
@@ -512,7 +512,7 @@
 }
 
 unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
-    void ** slots, unsigned char * code,
+    void ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff, 
     typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
     sal_Int32 /* functionCount */, sal_Int32 vTableOffset)
 {
@@ -523,7 +523,7 @@
         switch (member->eTypeClass) {
         case typelib_TypeClass_INTERFACE_ATTRIBUTE:
             // Getter:
-            *slots++ = code;
+            *slots++ = code + writetoexecdiff;
             code = codeSnippet(
                 code, functionOffset++, vTableOffset,
                 bridges::cpp_uno::shared::isSimpleType(
@@ -535,13 +535,13 @@
                 typelib_InterfaceAttributeTypeDescription * >(
                     member)->bReadOnly)
             {
-                *slots++ = code;
+                *slots++ = code + writetoexecdiff;
                 code = codeSnippet(code, functionOffset++, vTableOffset, true);
             }
             break;
 
         case typelib_TypeClass_INTERFACE_METHOD:
-            *slots++ = code;
+            *slots++ = code + writetoexecdiff;
             code = codeSnippet(
                 code, functionOffset++, vTableOffset,
                 bridges::cpp_uno::shared::isSimpleType(
--- bridges/source/cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx	2007-06-05 13:55:15.000000000 +0100
+++ bridges/source/cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx	2007-06-05 13:56:12.000000000 +0100
@@ -666,7 +666,7 @@
 }
 
 unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
-    void ** slots, unsigned char * code, 
+    void ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
     typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
     sal_Int32 functionCount, sal_Int32 vtableOffset)
 {
@@ -682,7 +682,7 @@
         switch (member->eTypeClass) {
         case typelib_TypeClass_INTERFACE_ATTRIBUTE:
             // Getter:
-            *slots++ = code;
+            *slots++ = code + writetoexecdiff;
             code = codeSnippet(
                 code, functionOffset++, vtableOffset,
                 bridges::cpp_uno::shared::isSimpleType(
@@ -695,13 +695,13 @@
                 typelib_InterfaceAttributeTypeDescription * >(
                     member)->bReadOnly)
             {
-                *slots++ = code;
+                *slots++ = code + writetoexecdiff;
                 code = codeSnippet(code, functionOffset++, vtableOffset, true);
             }
             break;
 
         case typelib_TypeClass_INTERFACE_METHOD:
-            *slots++ = code;
+            *slots++ = code + writetoexecdiff;
             code = codeSnippet(
                 code, functionOffset++, vtableOffset,
                 bridges::cpp_uno::shared::isSimpleType(
