This is an automated email from the ASF dual-hosted git repository.

truckman pushed a commit to branch AOO418
in repository https://gitbox.apache.org/repos/asf/openoffice.git

commit 0bd9e244a1c349a04bd0330cfab559b72298733c
Author: pfg <pfg@13f79535-47bb-0310-9956-ffa450edef68>
AuthorDate: Tue Jan 3 04:15:40 2017 +0000

    Initial support for the FreeBSD ARM platform.
    
    This is just the skeleton, basically a copy of the linux support.
    It wouldn't be surprising if it works without much trouble.
    
    
    git-svn-id: https://svn.apache.org/repos/asf/openoffice/trunk@1777057 
13f79535-47bb-0310-9956-ffa450edef68
---
 .../source/cpp_uno/gcc3_freebsd_arm/armhelper.S    |  57 ++
 .../source/cpp_uno/gcc3_freebsd_arm/cpp2uno.cxx    | 546 +++++++++++++++++
 .../source/cpp_uno/gcc3_freebsd_arm/except.cxx     | 337 +++++++++++
 .../source/cpp_uno/gcc3_freebsd_arm/makefile.mk    |  80 +++
 .../source/cpp_uno/gcc3_freebsd_arm/share.hxx      |  96 +++
 .../source/cpp_uno/gcc3_freebsd_arm/uno2cpp.cxx    | 665 +++++++++++++++++++++
 main/set_soenv.in                                  |  11 +
 main/solenv/inc/unxfbsd.mk                         |   3 +
 main/solenv/inc/unxfbsdr.mk                        |  46 ++
 9 files changed, 1841 insertions(+)

diff --git a/main/bridges/source/cpp_uno/gcc3_freebsd_arm/armhelper.S 
b/main/bridges/source/cpp_uno/gcc3_freebsd_arm/armhelper.S
new file mode 100644
index 0000000..577403d
--- /dev/null
+++ b/main/bridges/source/cpp_uno/gcc3_freebsd_arm/armhelper.S
@@ -0,0 +1,57 @@
+@   
+@   Licensed to the Apache Software Foundation (ASF) under one
+@   or more contributor license agreements.  See the NOTICE file
+@   distributed with this work for additional information
+@   regarding copyright ownership.  The ASF licenses this file
+@   to you under the Apache License, Version 2.0 (the
+@   "License"); you may not use this file except in compliance
+@   with the License.  You may obtain a copy of the License at
+@   
+@     http://www.apache.org/licenses/LICENSE-2.0
+@   
+@   Unless required by applicable law or agreed to in writing,
+@   software distributed under the License is distributed on an
+@   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@   KIND, either express or implied.  See the License for the
+@   specific language governing permissions and limitations
+@   under the License.
+@  
+
+@ ARM support code for OpenOffice C++/UNO bridging
+@
+@ Written by Peter Naulls <pe...@chocky.org>
+@ Modified by Caolan McNamara <caol...@redhat.com>
+@ Fixed by Michael Casadevall <mcasadev...@kubuntu.org>
+
+#ifdef __ARM_EABI__
+#  define UNWIND
+#else
+#  define UNWIND @
+#endif
+
+       .file   "armhelper.s"
+       .text
+       .align  4
+       .global privateSnippetExecutor
+       .type privateSnippetExecutor, %function
+privateSnippetExecutor:
+       UNWIND .fnstart            @ start of unwinder entry
+
+       stmfd sp!, {r0-r3}         @ follow other parameters on stack
+       UNWIND .pad  #16           @ throw this data away on exception
+       mov   r0, ip               @ r0 points to functionoffset/vtable
+       mov   r1, sp               @ r1 points to this and params
+                                  @ (see cppuno.cxx:codeSnippet())
+       stmfd sp!, {r4,lr}         @ save return address 
+                                  @ (r4 pushed to preserve stack alignment)
+       UNWIND .save {r4,lr}       @ restore these regs on exception
+
+       bl    cpp_vtable_call(PLT)
+
+       add   sp, sp, #4           @ no need to restore r4 (we didn't touch it)
+       ldr   pc, [sp], #20        @ return, discarding function arguments
+
+       UNWIND .fnend              @ end of unwinder entry
+
+       .size privateSnippetExecutor, . - privateSnippetExecutor
+        .section        .note.GNU-stack,"",%progbits
diff --git a/main/bridges/source/cpp_uno/gcc3_freebsd_arm/cpp2uno.cxx 
b/main/bridges/source/cpp_uno/gcc3_freebsd_arm/cpp2uno.cxx
new file mode 100644
index 0000000..bcc5f8e
--- /dev/null
+++ b/main/bridges/source/cpp_uno/gcc3_freebsd_arm/cpp2uno.cxx
@@ -0,0 +1,546 @@
+/**************************************************************
+ * 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * 
+ *************************************************************/
+
+
+
+#include <malloc.h>
+#include <hash_map>
+
+#include <rtl/alloc.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/vtablefactory.hxx"
+
+#include "share.hxx"
+
+#include <dlfcn.h>
+
+
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+    static typelib_TypeClass cpp2uno_call(
+        bridges::cpp_uno::shared::CppInterfaceProxy* pThis,
+        const typelib_TypeDescription * pMemberTypeDescr,
+        typelib_TypeDescriptionReference * pReturnTypeRef, 
+        sal_Int32 nParams, typelib_MethodParameter * pParams,
+        void ** pCallStack,
+        sal_Int64 * pRegisterReturn /* space for register return */ )
+    {
+        // pCallStack: ret, [return ptr], this, params
+        char * pTopStack = (char *)(pCallStack + 0);
+        char * pCppStack = pTopStack;
+
+        // return
+        typelib_TypeDescription * pReturnTypeDescr = 0;
+        if (pReturnTypeRef)
+            TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+        
+        void * pUnoReturn = 0;
+        // complex return ptr: if != 0 && != pUnoReturn, reconversion need
+        void * pCppReturn = 0;
+        
+        if (pReturnTypeDescr)
+        {
+            if (!arm::return_in_hidden_param(pReturnTypeRef))
+                pUnoReturn = pRegisterReturn; // direct way for simple types
+            else // complex return via ptr (pCppReturn)
+            {
+                pCppReturn = *(void **)pCppStack;
+                pCppStack += sizeof(void *);
+                
+                pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType(
+                    pReturnTypeDescr )
+                        ? alloca( pReturnTypeDescr->nSize )
+                        : pCppReturn); // direct way
+            }
+        }
+        // pop this
+        pCppStack += sizeof( void* );
+
+        // stack space
+        OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32),
+            "### unexpected size!" );
+        // parameters
+        void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
+        void ** pCppArgs = pUnoArgs + nParams;
+        // indizes of values this have to be converted (interface conversion
+        // cpp<=>uno)
+        sal_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams));
+        // type descriptions for reconversions
+        typelib_TypeDescription ** ppTempParamTypeDescr = 
+            (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
+        
+        sal_Int32 nTempIndizes   = 0;
+
+        for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+        {
+            const typelib_MethodParameter & rParam = pParams[nPos];
+            typelib_TypeDescription * pParamTypeDescr = 0;
+            TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+            if (!rParam.bOut && 
+                bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr )) 
+            {
+#ifdef __ARM_EABI__
+                switch (pParamTypeDescr->eTypeClass)
+                {
+                    case typelib_TypeClass_HYPER:
+                    case typelib_TypeClass_UNSIGNED_HYPER:
+                    case typelib_TypeClass_DOUBLE:
+                       if ((pCppStack - pTopStack) % 8) 
pCppStack+=sizeof(sal_Int32); //align to 8
+                        break;
+                    default:
+                        break;
+                }
+#endif
+
+                pCppArgs[nPos] = pCppStack;
+                pUnoArgs[nPos] = pCppStack;
+                switch (pParamTypeDescr->eTypeClass)
+                {
+                    case typelib_TypeClass_HYPER:
+                    case typelib_TypeClass_UNSIGNED_HYPER:
+                    case typelib_TypeClass_DOUBLE:
+                        pCppStack += sizeof(sal_Int32); // extra long
+                        break;
+                    default:
+                        break;
+                }
+                // no longer needed
+                TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+            }
+            else // ptr to complex value | ref
+            {
+                pCppArgs[nPos] = *(void **)pCppStack;
+
+                if (! rParam.bIn) // is pure out
+                {
+                    // uno out is unconstructed mem!
+                    pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
+                    pTempIndizes[nTempIndizes] = nPos;
+                    // will be released at reconversion
+                    ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+                }
+                // is in/inout
+                else if (bridges::cpp_uno::shared::relatesToInterfaceType(
+                    pParamTypeDescr ))
+                {
+                    uno_copyAndConvertData( pUnoArgs[nPos] = 
+                        alloca( pParamTypeDescr->nSize ),
+                        *(void **)pCppStack, pParamTypeDescr,
+                        pThis->getBridge()->getCpp2Uno() );
+                    pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+                    // will be released at reconversion
+                    ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+                }
+                else // direct way
+                {
+                    pUnoArgs[nPos] = *(void **)pCppStack;
+                    // no longer needed
+                    TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+                }
+            }
+            pCppStack += sizeof(sal_Int32); // standard parameter length
+        }
+        
+        // ExceptionHolder
+        uno_Any aUnoExc; // Any will be constructed by callee
+        uno_Any * pUnoExc = &aUnoExc;
+
+        // invoke uno dispatch call
+        (*pThis->getUnoI()->pDispatcher)(
+          pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
+
+        // in case an exception occurred...
+        if (pUnoExc)
+        {
+            // destruct temporary in/inout params
+            for ( ; nTempIndizes--; )
+            {
+                sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+                
+                if (pParams[nIndex].bIn) // is in/inout => was constructed
+                    uno_destructData( pUnoArgs[nIndex], 
+                        ppTempParamTypeDescr[nTempIndizes], 0 );
+                TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+            }
+            if (pReturnTypeDescr)
+                TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+            
+            CPPU_CURRENT_NAMESPACE::raiseException( &aUnoExc, 
+                pThis->getBridge()->getUno2Cpp() ); // has to destruct the any
+            // is here for dummy
+            return typelib_TypeClass_VOID;
+        }
+        else // else no exception occurred...
+        {
+            // temporary params
+            for ( ; nTempIndizes--; )
+            {
+                sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+                typelib_TypeDescription * pParamTypeDescr =
+                    ppTempParamTypeDescr[nTempIndizes];
+                
+                if (pParams[nIndex].bOut) // inout/out
+                {
+                    // convert and assign
+                    uno_destructData( pCppArgs[nIndex], pParamTypeDescr,
+                        cpp_release );
+                    uno_copyAndConvertData( pCppArgs[nIndex], 
pUnoArgs[nIndex], 
+                        pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
+                }
+                // destroy temp uno param
+                uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
+                
+                TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+            }
+            // return
+            if (pCppReturn) // has complex return
+            {
+                if (pUnoReturn != pCppReturn) // needs reconversion
+                {
+                    uno_copyAndConvertData( pCppReturn, pUnoReturn,
+                        pReturnTypeDescr, pThis->getBridge()->getUno2Cpp() );
+                    // destroy temp uno return
+                    uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
+                }
+                // complex return ptr is set to eax
+                *(void **)pRegisterReturn = pCppReturn;
+            }
+            if (pReturnTypeDescr)
+            {
+                typelib_TypeClass eRet =
+                    (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+                TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+                return eRet;
+            }
+            else
+                return typelib_TypeClass_VOID;
+        }
+    }
+
+
+    //=====================================================================
+    static typelib_TypeClass cpp_mediate(
+        sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
+        void ** pCallStack,
+        sal_Int64 * pRegisterReturn /* space for register return */ )
+    {
+        OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
+
+        // pCallStack: [ret *], this, params
+        // _this_ ptr is patched cppu_XInterfaceProxy object
+        void *pThis;
+        if( nFunctionIndex & 0x80000000 )
+        {
+            nFunctionIndex &= 0x7fffffff;
+            pThis = pCallStack[1];
+        }
+        else
+        {
+            pThis = pCallStack[0];
+        }
+
+        pThis = static_cast< char * >(pThis) - nVtableOffset;
+        bridges::cpp_uno::shared::CppInterfaceProxy * pCppI = 
+            bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
+                pThis);
+            
+        typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
+
+        OSL_ENSURE( nFunctionIndex < 
pTypeDescr->nMapFunctionIndexToMemberIndex,
+            "### illegal vtable index!" );
+        if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
+        {
+            throw RuntimeException(
+                OUString::createFromAscii("illegal vtable index!"),
+                (XInterface *)pCppI );
+        }
+        
+        // determine called method
+        OSL_ENSURE( nFunctionIndex < 
pTypeDescr->nMapFunctionIndexToMemberIndex,
+            "### illegal vtable index!" );
+        sal_Int32 nMemberPos =
+            pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
+        OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers,
+            "### illegal member index!" );
+
+        TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+
+        typelib_TypeClass eRet;
+        switch (aMemberDescr.get()->eTypeClass)
+        {
+        case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+        {
+            if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] ==
+                nFunctionIndex)
+            {
+                // is GET method
+                eRet = cpp2uno_call(
+                    pCppI, aMemberDescr.get(),
+                    ((typelib_InterfaceAttributeTypeDescription 
*)aMemberDescr.get())->pAttributeTypeRef,
+                    0, 0, // no params
+                    pCallStack, pRegisterReturn );
+            }
+            else
+            {
+                // is SET method
+                typelib_MethodParameter aParam;
+                aParam.pTypeRef =
+                    ((typelib_InterfaceAttributeTypeDescription 
*)aMemberDescr.get())->pAttributeTypeRef;
+                aParam.bIn      = sal_True;
+                aParam.bOut     = sal_False;
+                
+                eRet = cpp2uno_call(
+                    pCppI, aMemberDescr.get(),
+                    0, // indicates void return
+                    1, &aParam,
+                    pCallStack, pRegisterReturn );
+            }
+            break;
+        }
+        case typelib_TypeClass_INTERFACE_METHOD:
+        {
+            // is METHOD
+            switch (nFunctionIndex)
+            {
+            case 1: // acquire()
+                pCppI->acquireProxy(); // non virtual call!
+                eRet = typelib_TypeClass_VOID;
+                break;
+            case 2: // release()
+                pCppI->releaseProxy(); // non virtual call!
+                eRet = typelib_TypeClass_VOID;
+                break;
+            case 0: // queryInterface() opt
+            {
+                typelib_TypeDescription * pTD = 0;
+                TYPELIB_DANGER_GET(&pTD,
+                    reinterpret_cast<Type *>(pCallStack[2])->getTypeLibType());
+                if (pTD)
+                {
+                    XInterface * pInterface = 0;
+                    (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)(
+                        pCppI->getBridge()->getCppEnv(),
+                        (void **)&pInterface, pCppI->getOid().pData,
+                        (typelib_InterfaceTypeDescription *)pTD );
+                
+                    if (pInterface)
+                    {
+                        ::uno_any_construct(
+                            reinterpret_cast< uno_Any * >( pCallStack[0] ),
+                            &pInterface, pTD, cpp_acquire );
+                        pInterface->release();
+                        TYPELIB_DANGER_RELEASE( pTD );
+                        *(void **)pRegisterReturn = pCallStack[0];
+                        eRet = typelib_TypeClass_ANY;
+                        break;
+                    }
+                    TYPELIB_DANGER_RELEASE( pTD );
+                }
+            } // else perform queryInterface()
+            default:
+                eRet = cpp2uno_call(
+                    pCppI, aMemberDescr.get(),
+                    ((typelib_InterfaceMethodTypeDescription 
*)aMemberDescr.get())->pReturnTypeRef,
+                    ((typelib_InterfaceMethodTypeDescription 
*)aMemberDescr.get())->nParams,
+                    ((typelib_InterfaceMethodTypeDescription 
*)aMemberDescr.get())->pParams,
+                    pCallStack, pRegisterReturn );
+            }
+            break;
+        }
+        default:
+        {
+            throw RuntimeException(
+                OUString::createFromAscii("no member description found!"),
+                (XInterface *)pCppI );
+            // is here for dummy
+            eRet = typelib_TypeClass_VOID;
+        }
+        }
+
+        return eRet;
+    }
+}
+
+//=======================================================================
+/**
+ * is called on incoming vtable calls
+ * (called by asm snippets)
+ */
+
+extern "C" sal_Int64 cpp_vtable_call( long *pFunctionAndOffset, 
+    void **pCallStack )
+{
+    sal_Int64 nRegReturn;
+    typelib_TypeClass aType = cpp_mediate( pFunctionAndOffset[0], 
pFunctionAndOffset[1], pCallStack,
+        &nRegReturn );
+
+    switch( aType )
+    {
+        case typelib_TypeClass_BOOLEAN:
+        case typelib_TypeClass_BYTE:
+            nRegReturn = (unsigned long)(*(unsigned char *)&nRegReturn);
+            break;
+        case typelib_TypeClass_CHAR:
+        case typelib_TypeClass_UNSIGNED_SHORT:
+        case typelib_TypeClass_SHORT:
+            nRegReturn = (unsigned long)(*(unsigned short *)&nRegReturn);
+            break;
+        case typelib_TypeClass_ENUM:
+        case typelib_TypeClass_UNSIGNED_LONG:
+        case typelib_TypeClass_LONG:
+            nRegReturn = (unsigned long)(*(unsigned int *)&nRegReturn);
+            break;
+        case typelib_TypeClass_VOID:
+        default:
+            break;
+    }
+
+    return nRegReturn;
+}
+
+extern "C" void privateSnippetExecutor(void);
+
+namespace
+{
+    const int codeSnippetSize = 20;
+
+    unsigned char *codeSnippet(unsigned char* code, sal_Int32 functionIndex, 
+        sal_Int32 vtableOffset, bool bHasHiddenParam)
+    {
+        if (bHasHiddenParam)
+            functionIndex |= 0x80000000;
+
+        unsigned long * p = (unsigned long *)code;
+
+        *p++ = 0xE1A0C00F;
+        *p++ = 0xE59FF004;
+        *p++ = (unsigned long)functionIndex;
+        *p++ = (unsigned long)vtableOffset;
+        *p++ = (unsigned long)privateSnippetExecutor;
+
+        return code + codeSnippetSize;
+    }
+}
+
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
+{
+    return static_cast< Slot * >(block) + 2;
+}
+
+sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
+    sal_Int32 slotCount)
+{
+    return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
+}
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::initializeBlock(
+    void * block, sal_Int32 slotCount)
+{
+    Slot * slots = mapBlockToVtable(block);
+    slots[-2].fn = 0;
+    slots[-1].fn = 0;
+    return slots + slotCount;
+}
+
+unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
+    Slot ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
+    typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
+    sal_Int32 functionCount, sal_Int32 vtableOffset)
+{
+    (*slots) -= functionCount;
+    Slot * s = *slots;
+    for (sal_Int32 i = 0; i < type->nMembers; ++i)
+    {
+        typelib_TypeDescription * member = 0;
+        TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
+        OSL_ASSERT(member != 0);
+        switch (member->eTypeClass)
+        {
+            case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+            {
+                typelib_InterfaceAttributeTypeDescription *pAttrTD =
+                    reinterpret_cast<typelib_InterfaceAttributeTypeDescription 
*>( member );
+
+                // Getter:
+                (s++)->fn = code + writetoexecdiff;
+                code = codeSnippet(
+                    code, functionOffset++, vtableOffset,
+                    arm::return_in_hidden_param( pAttrTD->pAttributeTypeRef ));
+
+                // Setter:
+                if (!pAttrTD->bReadOnly)
+                {
+                    (s++)->fn = code + writetoexecdiff;
+                    code = codeSnippet(
+                        code, functionOffset++, vtableOffset, false);
+                }
+                break;
+            }
+            case typelib_TypeClass_INTERFACE_METHOD:
+            {
+                (s++)->fn = code + writetoexecdiff;
+
+                typelib_InterfaceMethodTypeDescription *pMethodTD = 
+                    reinterpret_cast<
+                        typelib_InterfaceMethodTypeDescription * >(member);
+
+                code = codeSnippet(code, functionOffset++, vtableOffset,
+                    arm::return_in_hidden_param(pMethodTD->pReturnTypeRef));
+                break;
+            }
+        default:
+            OSL_ASSERT(false);
+            break;
+        }
+        TYPELIB_DANGER_RELEASE(member);
+    }
+    return code;
+}
+
+void bridges::cpp_uno::shared::VtableFactory::flushCode(
+    unsigned char const *beg, unsigned char const *end)
+{
+   static void (*clear_cache)(unsigned char const*, unsigned char const*)
+       = (void (*)(unsigned char const*, unsigned char const*))
+           dlsym(RTLD_DEFAULT, "__clear_cache");    
+   (*clear_cache)(beg, end);
+}
+
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/main/bridges/source/cpp_uno/gcc3_freebsd_arm/except.cxx 
b/main/bridges/source/cpp_uno/gcc3_freebsd_arm/except.cxx
new file mode 100644
index 0000000..981fa41
--- /dev/null
+++ b/main/bridges/source/cpp_uno/gcc3_freebsd_arm/except.cxx
@@ -0,0 +1,337 @@
+/**************************************************************
+ * 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * 
+ *************************************************************/
+
+
+
+#include <stdio.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <typelib/typedescription.hxx>
+#include <uno/any2.h>
+
+#include "share.hxx"
+
+
+using namespace ::std;
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+using namespace ::__cxxabiv1;
+
+extern sal_Int32 * pHack;
+extern sal_Int32 nHack;
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+    void dummy_can_throw_anything( char const * )
+    {
+    }
+
+    //===================================================================
+    static OUString toUNOname( char const * p ) SAL_THROW( () )
+    {
+#if OSL_DEBUG_LEVEL > 1
+        char const * start = p;
+#endif
+
+        // example: N3com3sun4star4lang24IllegalArgumentExceptionE
+
+        OUStringBuffer buf( 64 );
+        OSL_ASSERT( 'N' == *p );
+        ++p; // skip N
+
+        while ('E' != *p)
+        {
+            // read chars count
+            long n = (*p++ - '0');
+            while ('0' <= *p && '9' >= *p)
+            {
+                n *= 10;
+                n += (*p++ - '0');
+            }
+            buf.appendAscii( p, n );
+            p += n;
+            if ('E' != *p)
+                buf.append( (sal_Unicode)'.' );
+        }
+
+#if OSL_DEBUG_LEVEL > 1
+        OUString ret( buf.makeStringAndClear() );
+        OString c_ret( OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US ) );
+        fprintf( stderr, "> toUNOname(): %s => %s\n", start, c_ret.getStr() );
+        return ret;
+#else
+        return buf.makeStringAndClear();
+#endif
+    }
+
+    //=====================================================================
+    class RTTI
+    {
+        typedef hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+        Mutex m_mutex;
+        t_rtti_map m_rttis;
+        t_rtti_map m_generatedRttis;
+
+        void * m_hApp;
+
+    public:
+        RTTI() SAL_THROW( () );
+        ~RTTI() SAL_THROW( () );
+
+        type_info * getRTTI(typelib_CompoundTypeDescription *) SAL_THROW( () );
+    };
+    //____________________________________________________________________
+    RTTI::RTTI() SAL_THROW( () )
+        : m_hApp( dlopen( 0, RTLD_LAZY ) )
+    {
+    }
+    //____________________________________________________________________
+    RTTI::~RTTI() SAL_THROW( () )
+    {
+        dlclose( m_hApp );
+    }
+
+    //____________________________________________________________________
+    type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) 
SAL_THROW( () )
+    {
+        type_info * rtti;
+
+        OUString const & unoName = *(OUString const 
*)&pTypeDescr->aBase.pTypeName;
+
+        MutexGuard guard( m_mutex );
+        t_rtti_map::const_iterator iFind( m_rttis.find( unoName ) );
+        if (iFind == m_rttis.end())
+        {
+            // RTTI symbol
+            OStringBuffer buf( 64 );
+            buf.append( RTL_CONSTASCII_STRINGPARAM("_ZTIN") );
+            sal_Int32 index = 0;
+            do
+            {
+                OUString token( unoName.getToken( 0, '.', index ) );
+                buf.append( token.getLength() );
+                OString c_token( OUStringToOString( token, 
RTL_TEXTENCODING_ASCII_US ) );
+                buf.append( c_token );
+            }
+            while (index >= 0);
+            buf.append( 'E' );
+
+            OString symName( buf.makeStringAndClear() );
+            rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+
+            if (rtti)
+            {
+                pair< t_rtti_map::iterator, bool > insertion(
+                    m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) 
);
+                OSL_ENSURE( insertion.second, "### inserting new rtti 
failed?!" );
+            }
+            else
+            {
+                // try to lookup the symbol in the generated rtti map
+                t_rtti_map::const_iterator iFind2( m_generatedRttis.find( 
unoName ) );
+                if (iFind2 == m_generatedRttis.end())
+                {
+                    // we must generate it !
+                    // symbol and rtti-name is nearly identical,
+                    // the symbol is prefixed with _ZTI
+                    char const * rttiName = symName.getStr() +4;
+#if OSL_DEBUG_LEVEL > 1
+                    fprintf( stderr,"generated rtti for %s\n", rttiName );
+#endif
+                    if (pTypeDescr->pBaseTypeDescription)
+                    {
+                        // ensure availability of base
+                        type_info * base_rtti = getRTTI(
+                            (typelib_CompoundTypeDescription 
*)pTypeDescr->pBaseTypeDescription );
+                        rtti = new __si_class_type_info(
+                            strdup( rttiName ), (__class_type_info *)base_rtti 
);
+                    }
+                    else
+                    {
+                        // this class has no base class
+                        rtti = new __class_type_info( strdup( rttiName ) );
+                    }
+
+                    pair< t_rtti_map::iterator, bool > insertion(
+                        m_generatedRttis.insert( t_rtti_map::value_type( 
unoName, rtti ) ) );
+                    OSL_ENSURE( insertion.second, "### inserting new generated 
rtti failed?!" );
+                }
+                else // taking already generated rtti
+                {
+                    rtti = iFind2->second;
+                }
+            }
+        }
+        else
+        {
+            rtti = iFind->second;
+        }
+
+        return rtti;
+    }
+
+    //------------------------------------------------------------------
+    static void deleteException( void * pExc )
+    {
+        __cxa_exception const * header = ((__cxa_exception const *)pExc - 1);
+        typelib_TypeDescription * pTD = 0;
+        OUString unoName( toUNOname( header->exceptionType->name() ) );
+        ::typelib_typedescription_getByName( &pTD, unoName.pData );
+        OSL_ENSURE( pTD, "### unknown exception type! leaving out destruction 
=> leaking!!!" );
+        if (pTD)
+        {
+            ::uno_destructData( pExc, pTD, cpp_release );
+            ::typelib_typedescription_release( pTD );
+        }
+    }
+
+    //==================================================================
+    void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
+    {
+#if OSL_DEBUG_LEVEL > 1
+        OString cstr(
+            OUStringToOString(
+                *reinterpret_cast< OUString const * >( 
&pUnoExc->pType->pTypeName ),
+                RTL_TEXTENCODING_ASCII_US ) );
+        fprintf( stderr, "> uno exception occurred: %s\n", cstr.getStr() );
+#endif
+        void * pCppExc;
+        type_info * rtti;
+
+        {
+        // construct cpp exception object
+        typelib_TypeDescription * pTypeDescr = 0;
+        TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
+        OSL_ASSERT( pTypeDescr );
+        if (! pTypeDescr)
+        {
+            throw RuntimeException(
+                OUString( RTL_CONSTASCII_USTRINGPARAM("cannot get 
typedescription for type ") ) +
+                *reinterpret_cast< OUString const * >( 
&pUnoExc->pType->pTypeName ),
+                Reference< XInterface >() );
+        }
+
+        pCppExc = __cxa_allocate_exception( pTypeDescr->nSize );
+        ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, 
pUno2Cpp );
+
+        // destruct uno exception
+        ::uno_any_destruct( pUnoExc, 0 );
+        // avoiding locked counts
+        static RTTI * s_rtti = 0;
+        if (! s_rtti)
+        {
+            MutexGuard guard( Mutex::getGlobalMutex() );
+            if (! s_rtti)
+            {
+#ifdef LEAK_STATIC_DATA
+                s_rtti = new RTTI();
+#else
+                static RTTI rtti_data;
+                s_rtti = &rtti_data;
+#endif
+            }
+        }
+        rtti = (type_info *)s_rtti->getRTTI( (typelib_CompoundTypeDescription 
*) pTypeDescr );
+        TYPELIB_DANGER_RELEASE( pTypeDescr );
+        OSL_ENSURE( rtti, "### no rtti for throwing exception!" );
+        if (! rtti)
+        {
+            throw RuntimeException(
+                OUString( RTL_CONSTASCII_USTRINGPARAM("no rtti for type ") ) +
+                *reinterpret_cast< OUString const * >( 
&pUnoExc->pType->pTypeName ),
+                Reference< XInterface >() );
+        }
+        }
+
+
+       __cxa_throw( pCppExc, rtti, deleteException );
+    }
+
+#ifdef __ARM_EABI__
+    static void* getAdjustedPtr(__cxa_exception* header)
+    {
+        return (void*)header->unwindHeader.barrier_cache.bitpattern[0];
+    }
+#else
+    static void* getAdjustedPtr(__cxa_exception* header)
+    {
+        return header->adjustedPtr;
+    }
+#endif
+
+    //===================================================================
+    void fillUnoException( __cxa_exception * header, uno_Any * pUnoExc, 
uno_Mapping * pCpp2Uno )
+    {
+        if (! header)
+        {
+            RuntimeException aRE(
+                OUString( RTL_CONSTASCII_USTRINGPARAM("no exception header!") 
),
+                Reference< XInterface >() );
+            Type const & rType = ::getCppuType( &aRE );
+            uno_type_any_constructAndConvert( pUnoExc, &aRE, 
rType.getTypeLibType(), pCpp2Uno );
+#if OSL_DEBUG_LEVEL > 0
+            OString cstr( OUStringToOString( aRE.Message, 
RTL_TEXTENCODING_ASCII_US ) );
+            OSL_ENSURE( 0, cstr.getStr() );
+#endif
+            return;
+        }
+
+        typelib_TypeDescription * pExcTypeDescr = 0;
+        OUString unoName( toUNOname( header->exceptionType->name() ) );
+#if OSL_DEBUG_LEVEL > 1
+        OString cstr_unoName( OUStringToOString( unoName, 
RTL_TEXTENCODING_ASCII_US ) );
+        fprintf( stderr, "> c++ exception occurred: %s\n", 
cstr_unoName.getStr() );
+#endif
+        typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+        if (0 == pExcTypeDescr)
+        {
+            RuntimeException aRE(
+                OUString( RTL_CONSTASCII_USTRINGPARAM("exception type not 
found: ") ) + unoName,
+                Reference< XInterface >() );
+            Type const & rType = ::getCppuType( &aRE );
+            uno_type_any_constructAndConvert( pUnoExc, &aRE, 
rType.getTypeLibType(), pCpp2Uno );
+#if OSL_DEBUG_LEVEL > 0
+            OString cstr( OUStringToOString( aRE.Message, 
RTL_TEXTENCODING_ASCII_US ) );
+            OSL_ENSURE( 0, cstr.getStr() );
+#endif
+        }
+        else
+        {
+            // construct uno exception any
+            uno_any_constructAndConvert( pUnoExc, getAdjustedPtr(header), 
pExcTypeDescr, pCpp2Uno );
+            typelib_typedescription_release( pExcTypeDescr );
+        }
+    }
+}
+
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/main/bridges/source/cpp_uno/gcc3_freebsd_arm/makefile.mk 
b/main/bridges/source/cpp_uno/gcc3_freebsd_arm/makefile.mk
new file mode 100644
index 0000000..1672cdf
--- /dev/null
+++ b/main/bridges/source/cpp_uno/gcc3_freebsd_arm/makefile.mk
@@ -0,0 +1,80 @@
+#**************************************************************
+#  
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#  
+#    http://www.apache.org/licenses/LICENSE-2.0
+#  
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#  
+#**************************************************************
+
+
+
+PRJ=..$/..$/..
+
+PRJNAME=bridges
+TARGET=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+NO_BSYMBOLIC=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE :  settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)$(OS)$(CPU)$(COMNAME)" == "GCCLINUXRgcc3"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+CFLAGSCXX += -fno-omit-frame-pointer 
+
+NOOPTFILES= \
+       $(SLO)$/cpp2uno.obj \
+       $(SLO)$/except.obj \
+       $(SLO)$/uno2cpp.obj
+
+CFLAGSNOOPT=-O0
+
+SLOFILES= \
+       $(SLO)$/cpp2uno.obj \
+       $(SLO)$/except.obj \
+       $(SLO)$/uno2cpp.obj \
+       $(SLO)$/armhelper.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH=URELIB
+
+SHL1OBJS = $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+       $(CPPULIB)                      \
+       $(SALLIB)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE :  target.mk
+
+$(SLO)$/%.obj: %.S
+       $(CXX) -c -o $(SLO)$/$(@:b).o $< -fPIC ; touch $@
diff --git a/main/bridges/source/cpp_uno/gcc3_freebsd_arm/share.hxx 
b/main/bridges/source/cpp_uno/gcc3_freebsd_arm/share.hxx
new file mode 100644
index 0000000..df4e6dc
--- /dev/null
+++ b/main/bridges/source/cpp_uno/gcc3_freebsd_arm/share.hxx
@@ -0,0 +1,96 @@
+/**************************************************************
+ * 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * 
+ *************************************************************/
+
+
+#ifndef _ARM_SHARE_HXX
+#define _ARM_SHARE_HXX
+#include "uno/mapping.h"
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+#include <unwind.h>
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+    void dummy_can_throw_anything( char const * );
+
+    // -- following decl from libstdc++-v3/libsupc++/unwind-cxx.h and unwind.h
+
+    struct __cxa_exception
+    { 
+        ::std::type_info *exceptionType;
+        void (*exceptionDestructor)(void *); 
+        
+        ::std::unexpected_handler unexpectedHandler;
+        ::std::terminate_handler terminateHandler;
+        
+        __cxa_exception *nextException;
+        
+        int handlerCount;
+#ifdef __ARM_EABI__
+       __cxa_exception *nextPropagatingException;
+       int propagationCount;
+#else
+        int handlerSwitchValue;
+        const unsigned char *actionRecord;
+        const unsigned char *languageSpecificData;
+        void *catchTemp;
+        void *adjustedPtr;
+#endif    
+        _Unwind_Exception unwindHeader;
+    };    
+
+    extern "C" void *__cxa_allocate_exception(
+        std::size_t thrown_size ) throw();
+    extern "C" void __cxa_throw (
+        void *thrown_exception, std::type_info *tinfo, 
+        void (*dest) (void *) ) __attribute__((noreturn));
+
+    struct __cxa_eh_globals
+    {
+        __cxa_exception *caughtExceptions;
+        unsigned int uncaughtExceptions;
+#ifdef __ARM_EABI__
+       __cxa_exception *propagatingExceptions;
+#endif
+    };
+    extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+    // -----
+
+    //====================================================================
+    void raiseException(
+        uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+    //====================================================================
+    void fillUnoException(
+        __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
+
+namespace arm
+{
+    enum armlimits { MAX_GPR_REGS = 4 };
+    bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef );
+}
+
+#endif
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/main/bridges/source/cpp_uno/gcc3_freebsd_arm/uno2cpp.cxx 
b/main/bridges/source/cpp_uno/gcc3_freebsd_arm/uno2cpp.cxx
new file mode 100644
index 0000000..daf14dc
--- /dev/null
+++ b/main/bridges/source/cpp_uno/gcc3_freebsd_arm/uno2cpp.cxx
@@ -0,0 +1,665 @@
+/**************************************************************
+ * 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * 
+ *************************************************************/
+
+
+
+#include <malloc.h>
+#include <rtl/alloc.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.h>
+
+#include <bridges/cpp_uno/shared/bridge.hxx>
+#include <bridges/cpp_uno/shared/types.hxx>
+#include <bridges/cpp_uno/shared/unointerfaceproxy.hxx>
+#include <bridges/cpp_uno/shared/vtables.hxx>
+
+#include "share.hxx"
+
+#include <stdio.h>
+#include <string.h>
+
+/* 
+ * Based on http://gcc.gnu.org/PR41443
+ * References to __SOFTFP__ are incorrect for EABI; the __SOFTFP__ code
+ * should be used for *soft-float ABI* whether or not VFP is enabled,
+ * and __SOFTFP__ does specifically mean soft-float not soft-float ABI.
+ *
+ * Changing the conditionals to __SOFTFP__ || __ARM_EABI__ then 
+ * -mfloat-abi=softfp should work.  -mfloat-abi=hard won't; that would
+ * need both a new macro to identify the hard-VFP ABI.
+ */
+#if !defined(__ARM_EABI__) && !defined(__SOFTFP__)
+#error Not Implemented
+
+/*
+ some possibly handy code to detect that we have VFP registers
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <elf.h>
+
+#define HWCAP_ARM_VFP 64
+
+int hasVFP(void)
+{
+    int fd = open ("/proc/self/auxv", O_RDONLY);
+    if (fd == -1)
+        return -1;
+
+    int ret = -1;
+
+    Elf32_auxv_t buf[128];
+    ssize_t n;
+    while ((ret == -1) && ((n = read(fd, buf, sizeof (buf))) > 0))
+    {
+        for (int i = 0; i < 128; ++i)
+        {
+           if (buf[i].a_type == AT_HWCAP)
+           {
+                ret = (buf[i].a_un.a_val & HWCAP_ARM_VFP) ? true : false;
+                break;
+           }
+            else if (buf[i].a_type == AT_NULL)
+            {
+                ret = -2;
+                break;
+            }
+        }
+    }
+
+    close (fd);
+    return ret;
+}
+
+#endif
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace arm
+{
+    bool is_complex_struct(const typelib_TypeDescription * type)
+    {
+        const typelib_CompoundTypeDescription * p
+            = reinterpret_cast< const typelib_CompoundTypeDescription * 
>(type);
+        for (sal_Int32 i = 0; i < p->nMembers; ++i)
+        {
+            if (p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_STRUCT ||
+                p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_EXCEPTION)
+            {
+                typelib_TypeDescription * t = 0;
+                TYPELIB_DANGER_GET(&t, p->ppTypeRefs[i]);
+                bool b = is_complex_struct(t);
+                TYPELIB_DANGER_RELEASE(t);
+                if (b) {
+                    return true;
+                }
+            }
+            else if 
(!bridges::cpp_uno::shared::isSimpleType(p->ppTypeRefs[i]->eTypeClass))
+                return true;
+        }
+        if (p->pBaseTypeDescription != 0)
+            return is_complex_struct(&p->pBaseTypeDescription->aBase);
+        return false;
+    }
+
+    bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef )
+    {
+        if (bridges::cpp_uno::shared::isSimpleType(pTypeRef))
+            return false;
+        else if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT || 
pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION)
+        {
+            typelib_TypeDescription * pTypeDescr = 0;
+            TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
+
+            //A Composite Type not larger than 4 bytes is returned in r0
+            bool bRet = pTypeDescr->nSize > 4 || is_complex_struct(pTypeDescr);
+
+            TYPELIB_DANGER_RELEASE( pTypeDescr );
+            return bRet;
+        }
+        return true;
+    }
+}
+
+void MapReturn(sal_uInt32 r0, sal_uInt32 r1, typelib_TypeDescriptionReference 
* pReturnType, sal_uInt32* pRegisterReturn)
+{
+#if !defined(__ARM_EABI__) && !defined(__SOFTFP__)
+    register float fret asm("f0");
+    register double dret asm("f0");
+#endif
+
+    switch( pReturnType->eTypeClass )
+    {
+        case typelib_TypeClass_HYPER:
+        case typelib_TypeClass_UNSIGNED_HYPER:
+            pRegisterReturn[1] = r1;
+        case typelib_TypeClass_LONG:
+        case typelib_TypeClass_UNSIGNED_LONG:
+        case typelib_TypeClass_ENUM:
+        case typelib_TypeClass_CHAR:
+        case typelib_TypeClass_SHORT:
+        case typelib_TypeClass_UNSIGNED_SHORT:
+        case typelib_TypeClass_BOOLEAN:
+        case typelib_TypeClass_BYTE:
+            pRegisterReturn[0] = r0;
+            break;
+        case typelib_TypeClass_FLOAT:
+#if defined(__ARM_EABI__) || defined(__SOFTFP__)
+            pRegisterReturn[0] = r0;
+#else
+            *(float*)pRegisterReturn = fret;
+#endif
+           break;
+        case typelib_TypeClass_DOUBLE:
+#if defined(__ARM_EABI__) || defined(__SOFTFP__)
+            pRegisterReturn[1] = r1;
+            pRegisterReturn[0] = r0;
+#else
+            *(double*)pRegisterReturn = dret;
+#endif
+            break;
+        case typelib_TypeClass_STRUCT:
+        case typelib_TypeClass_EXCEPTION:
+        {
+            if (!arm::return_in_hidden_param(pReturnType))
+                pRegisterReturn[0] = r0;
+            break;
+        }
+        default:
+            break;
+    }
+}
+
+namespace
+{
+//================================================================
+
+void callVirtualMethod(
+    void * pThis,
+    sal_Int32 nVtableIndex,
+    void * pRegisterReturn,
+    typelib_TypeDescriptionReference * pReturnType,
+    sal_uInt32 *pStack,
+    sal_uInt32 nStack,
+    sal_uInt32 *pGPR,
+    sal_uInt32 nGPR) __attribute__((noinline));
+
+void callVirtualMethod(
+    void * pThis,
+    sal_Int32 nVtableIndex,
+    void * pRegisterReturn,
+    typelib_TypeDescriptionReference * pReturnType,
+    sal_uInt32 *pStack,
+    sal_uInt32 nStack,
+    sal_uInt32 *pGPR,
+    sal_uInt32 nGPR)
+{
+    // never called
+    if (! pThis)
+        CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything("xxx"); // address 
something
+
+    if ( nStack )
+    {
+        // 8-bytes aligned
+        sal_uInt32 nStackBytes = ( ( nStack + 1 ) >> 1 ) * 8;
+        sal_uInt32 *stack = (sal_uInt32 *) __builtin_alloca( nStackBytes );
+        memcpy( stack, pStack, nStackBytes );
+    }
+
+    // Should not happen, but...
+    if ( nGPR > arm::MAX_GPR_REGS )
+        nGPR = arm::MAX_GPR_REGS;
+
+    sal_uInt32 pMethod = *((sal_uInt32*)pThis);
+    pMethod += 4 * nVtableIndex;
+    pMethod = *((sal_uInt32 *)pMethod);
+
+    typedef void (*FunctionCall )( sal_uInt32, sal_uInt32, sal_uInt32, 
sal_uInt32);
+    FunctionCall pFunc = (FunctionCall)pMethod;
+
+    (*pFunc)(pGPR[0], pGPR[1], pGPR[2], pGPR[3]);
+
+    sal_uInt32 r0;
+    sal_uInt32 r1;
+
+    // get return value
+    __asm__ __volatile__ (
+        "mov %0, r0\n\t"
+        "mov %1, r1\n\t"
+        : "=r" (r0), "=r" (r1) : );
+
+    MapReturn(r0, r1, pReturnType, (sal_uInt32*)pRegisterReturn);
+}
+}
+
+#define INSERT_INT32( pSV, nr, pGPR, pDS, bOverflow ) \
+        if ( nr < arm::MAX_GPR_REGS ) \
+                pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
+        else \
+                bOverFlow = true; \
+        if (bOverFlow) \
+                *pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV );
+
+#ifdef __ARM_EABI__
+#define INSERT_INT64( pSV, nr, pGPR, pDS, pStart, bOverflow ) \
+        if ( (nr < arm::MAX_GPR_REGS) && (nr % 2) ) \
+        { \
+               ++nr; \
+        } \
+        if ( nr < arm::MAX_GPR_REGS ) \
+        { \
+                pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
+                pGPR[nr++] = *(reinterpret_cast<sal_uInt32 *>( pSV ) + 1); \
+        } \
+        else \
+                bOverFlow = true; \
+        if (bOverFlow) \
+       { \
+               if ( (pDS - pStart) % 2) \
+                { \
+                       ++pDS; \
+                } \
+                *pDS++ = reinterpret_cast<sal_uInt32 *>( pSV )[0]; \
+                *pDS++ = reinterpret_cast<sal_uInt32 *>( pSV )[1]; \
+       }
+#else
+#define INSERT_INT64( pSV, nr, pGPR, pDS, pStart, bOverflow ) \
+        INSERT_INT32( pSV, nr, pGPR, pDS, bOverflow) \
+        INSERT_INT32( ((sal_uInt32*)pSV)+1, nr, pGPR, pDS, bOverflow)
+#endif
+
+#define INSERT_FLOAT( pSV, nr, pFPR, pDS, bOverflow ) \
+        INSERT_INT32( pSV, nr, pGPR, pDS, bOverflow)
+
+#define INSERT_DOUBLE( pSV, nr, pFPR, pDS, pStart, bOverflow ) \
+        INSERT_INT64( pSV, nr, pGPR, pDS, pStart, bOverflow )
+
+#define INSERT_INT16( pSV, nr, pGPR, pDS, bOverflow ) \
+        if ( nr < arm::MAX_GPR_REGS ) \
+                pGPR[nr++] = *reinterpret_cast<sal_uInt16 *>( pSV ); \
+        else \
+                bOverFlow = true; \
+        if (bOverFlow) \
+                *pDS++ = *reinterpret_cast<sal_uInt16 *>( pSV );
+
+#define INSERT_INT8( pSV, nr, pGPR, pDS, bOverflow ) \
+        if ( nr < arm::MAX_GPR_REGS ) \
+                pGPR[nr++] = *reinterpret_cast<sal_uInt8 *>( pSV ); \
+        else \
+                bOverFlow = true; \
+        if (bOverFlow) \
+                *pDS++ = *reinterpret_cast<sal_uInt8 *>( pSV );
+
+namespace {
+//======================================================================= 
+static void cpp_call(
+    bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
+    bridges::cpp_uno::shared::VtableSlot aVtableSlot,
+    typelib_TypeDescriptionReference * pReturnTypeRef,
+    sal_Int32 nParams, typelib_MethodParameter * pParams,
+    void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
+{
+    // max space for: [complex ret ptr], values|ptr ...
+    sal_uInt32 * pStack = (sal_uInt32 *)__builtin_alloca(
+        sizeof(sal_Int32) + ((nParams+2) * sizeof(sal_Int64)) );
+    sal_uInt32 * pStackStart = pStack;
+
+    sal_uInt32 pGPR[arm::MAX_GPR_REGS];
+    sal_uInt32 nGPR = 0;
+    
+    // return
+    typelib_TypeDescription * pReturnTypeDescr = 0;
+    TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+    OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
+    
+    void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
+
+    bool bOverFlow = false;
+    bool bSimpleReturn = true;
+    if (pReturnTypeDescr)
+    {
+        if (arm::return_in_hidden_param( pReturnTypeRef ) )
+            bSimpleReturn = false;
+
+        if (bSimpleReturn)
+            pCppReturn = pUnoReturn; // direct way for simple types
+        else
+        {
+            // complex return via ptr
+            pCppReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( 
pReturnTypeDescr )
+                    ? __builtin_alloca( pReturnTypeDescr->nSize )
+                    : pUnoReturn); // direct way
+
+            INSERT_INT32( &pCppReturn, nGPR, pGPR, pStack, bOverFlow );
+        }
+    }
+    // push this
+    void * pAdjustedThisPtr = reinterpret_cast< void ** >(pThis->getCppI())
+        + aVtableSlot.offset;
+    INSERT_INT32( &pAdjustedThisPtr, nGPR, pGPR, pStack, bOverFlow );
+
+    // stack space
+    OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+    // args
+    void ** pCppArgs  = (void **)alloca( 3 * sizeof(void *) * nParams );
+    // indizes of values this have to be converted (interface conversion 
cpp<=>uno)
+    sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams);
+    // type descriptions for reconversions
+    typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription 
**)(pCppArgs + (2 * nParams));
+
+    sal_Int32 nTempIndizes   = 0;
+    
+    for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+    {
+        const typelib_MethodParameter & rParam = pParams[nPos];
+        typelib_TypeDescription * pParamTypeDescr = 0;
+        TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+        if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( 
pParamTypeDescr ))
+        {
+//            uno_copyAndConvertData( pCppArgs[nPos] = pStack, pUnoArgs[nPos],
+            uno_copyAndConvertData( pCppArgs[nPos] = alloca(8), pUnoArgs[nPos],
+                pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
+            
+            switch (pParamTypeDescr->eTypeClass)
+            {
+            case typelib_TypeClass_HYPER:
+            case typelib_TypeClass_UNSIGNED_HYPER:
+#ifdef CMC_DEBUG
+                           fprintf(stderr, "hyper is %lx\n", pCppArgs[nPos]);
+#endif
+                INSERT_INT64( pCppArgs[nPos], nGPR, pGPR, pStack, pStackStart, 
bOverFlow );
+                break;
+            case typelib_TypeClass_LONG:
+            case typelib_TypeClass_UNSIGNED_LONG:
+            case typelib_TypeClass_ENUM:
+#ifdef CMC_DEBUG
+                           fprintf(stderr, "long is %x\n", pCppArgs[nPos]);
+#endif
+                INSERT_INT32( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
+                break;
+            case typelib_TypeClass_SHORT:
+            case typelib_TypeClass_CHAR:
+            case typelib_TypeClass_UNSIGNED_SHORT:
+                INSERT_INT16( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
+                break;
+            case typelib_TypeClass_BOOLEAN:
+            case typelib_TypeClass_BYTE:
+                INSERT_INT8( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
+                break;
+            case typelib_TypeClass_FLOAT:
+                INSERT_FLOAT( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
+                           break;
+            case typelib_TypeClass_DOUBLE:
+                INSERT_DOUBLE( pCppArgs[nPos], nGPR, pGPR, pStack, 
pStackStart, bOverFlow );
+                break;
+            default:
+                break;
+            }
+            // no longer needed
+            TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+        }
+        else // ptr to complex value | ref
+        {
+            if (! rParam.bIn) // is pure out
+            {
+                // cpp out is constructed mem, uno out is not!
+                uno_constructData(
+                    pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+                    pParamTypeDescr );
+                pTempIndizes[nTempIndizes] = nPos; // default constructed for 
cpp call
+                // will be released at reconversion
+                ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+            }
+            // is in/inout
+            else if (bridges::cpp_uno::shared::relatesToInterfaceType( 
pParamTypeDescr ))
+            {
+                uno_copyAndConvertData(
+                    pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+                    pUnoArgs[nPos], pParamTypeDescr, 
pThis->getBridge()->getUno2Cpp() );
+                
+                pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+                // will be released at reconversion
+                ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+            }
+            else // direct way
+            {
+                pCppArgs[nPos] = pUnoArgs[nPos];
+                // no longer needed
+                TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+            }
+            INSERT_INT32( &(pCppArgs[nPos]), nGPR, pGPR, pStack, bOverFlow );
+        }
+    }
+
+    try
+    {
+        callVirtualMethod(
+            pAdjustedThisPtr, aVtableSlot.index,
+            pCppReturn, pReturnTypeRef,
+            pStackStart, 
+            (pStack - pStackStart),
+            pGPR, nGPR);
+
+        // NO exception occurred...
+        *ppUnoExc = 0;
+
+        // reconvert temporary params
+        for ( ; nTempIndizes--; )
+        {
+            sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+            typelib_TypeDescription * pParamTypeDescr = 
ppTempParamTypeDescr[nTempIndizes];
+            
+            if (pParams[nIndex].bIn)
+            {
+                if (pParams[nIndex].bOut) // inout
+                {
+                    uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); 
// destroy uno value
+                    uno_copyAndConvertData( pUnoArgs[nIndex], 
pCppArgs[nIndex], pParamTypeDescr,
+                                            pThis->getBridge()->getCpp2Uno() );
+                }
+            }
+            else // pure out
+            {
+                uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], 
pParamTypeDescr,
+                                        pThis->getBridge()->getCpp2Uno() );
+            }
+            // destroy temp cpp param => cpp: every param was constructed
+            uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+            
+            TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+        }
+        // return value
+        if (pCppReturn && pUnoReturn != pCppReturn)
+        {
+            uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
+                                    pThis->getBridge()->getCpp2Uno() );
+            uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
+        }
+    }
+    catch (...)
+    {
+//        __asm__ __volatile__ ("sub sp, sp, #2048\n");
+
+        // fill uno exception
+        fillUnoException( 
CPPU_CURRENT_NAMESPACE::__cxa_get_globals()->caughtExceptions, *ppUnoExc, 
pThis->getBridge()->getCpp2Uno() );
+
+        // temporary params
+        for ( ; nTempIndizes--; )
+        {
+            sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+            // destroy temp cpp param => cpp: every param was constructed
+            uno_destructData( pCppArgs[nIndex], 
ppTempParamTypeDescr[nTempIndizes], cpp_release );
+            TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+        }
+        
+        // return type
+        if (pReturnTypeDescr)
+            TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+    }
+}
+}
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+void unoInterfaceProxyDispatch(
+    uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
+    void * pReturn, void * pArgs[], uno_Any ** ppException )
+{
+    // is my surrogate
+    bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
+          = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * 
>(pUnoI);
+#if OSL_DEBUG_LEVEL > 0
+    typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+#endif
+    
+    switch (pMemberDescr->eTypeClass)
+    {
+    case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+    {
+#if OSL_DEBUG_LEVEL > 0
+        // determine vtable call index
+        sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription 
*)pMemberDescr)->nPosition;
+        OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out 
of range!" );
+#endif
+        
+        VtableSlot aVtableSlot(
+            getVtableSlot(
+            reinterpret_cast<typelib_InterfaceAttributeTypeDescription const *>
+              (pMemberDescr)));
+        
+        if (pReturn)
+        {
+            // dependent dispatch
+            cpp_call(
+                pThis, aVtableSlot,
+                ((typelib_InterfaceAttributeTypeDescription 
*)pMemberDescr)->pAttributeTypeRef,
+                0, 0, // no params
+                pReturn, pArgs, ppException );
+        }
+        else
+        {
+            // is SET
+            typelib_MethodParameter aParam;
+            aParam.pTypeRef =
+                ((typelib_InterfaceAttributeTypeDescription 
*)pMemberDescr)->pAttributeTypeRef;
+            aParam.bIn      = sal_True;
+            aParam.bOut     = sal_False;
+
+            typelib_TypeDescriptionReference * pReturnTypeRef = 0;
+            OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") );
+            typelib_typedescriptionreference_new(
+                &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
+            
+            // dependent dispatch
+            aVtableSlot.index += 1;
+            cpp_call(
+                pThis, aVtableSlot, // get, then set method
+                pReturnTypeRef,
+                1, &aParam,
+                pReturn, pArgs, ppException );
+            
+            typelib_typedescriptionreference_release( pReturnTypeRef );
+        }
+        
+        break;
+    }
+    case typelib_TypeClass_INTERFACE_METHOD:
+    {
+#if OSL_DEBUG_LEVEL > 0
+        // determine vtable call index
+        sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription 
*)pMemberDescr)->nPosition;
+        OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out 
of range!" );
+#endif
+
+        VtableSlot aVtableSlot(
+            getVtableSlot(
+            reinterpret_cast<typelib_InterfaceMethodTypeDescription const *>
+              (pMemberDescr)));
+
+        switch (aVtableSlot.index)
+        {
+            // standard calls
+        case 1: // acquire uno interface
+            (*pUnoI->acquire)( pUnoI );
+            *ppException = 0;
+            break;
+        case 2: // release uno interface
+            (*pUnoI->release)( pUnoI );
+            *ppException = 0;
+            break;
+        case 0: // queryInterface() opt
+        {
+            typelib_TypeDescription * pTD = 0;
+            TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] 
)->getTypeLibType() );
+            if (pTD)
+            {
+                uno_Interface * pInterface = 0;
+                (*pThis->getBridge()->getUnoEnv()->getRegisteredInterface)(
+                    pThis->getBridge()->getUnoEnv(),
+                    (void **)&pInterface, pThis->oid.pData, 
(typelib_InterfaceTypeDescription *)pTD );
+            
+                if (pInterface)
+                {
+                    ::uno_any_construct(
+                        reinterpret_cast< uno_Any * >( pReturn ),
+                        &pInterface, pTD, 0 );
+                    (*pInterface->release)( pInterface );
+                    TYPELIB_DANGER_RELEASE( pTD );
+                    *ppException = 0;
+                    break;
+                }
+                TYPELIB_DANGER_RELEASE( pTD );
+            }
+        } // else perform queryInterface()
+        default:
+            // dependent dispatch
+            cpp_call(
+                pThis, aVtableSlot,
+                ((typelib_InterfaceMethodTypeDescription 
*)pMemberDescr)->pReturnTypeRef,
+                ((typelib_InterfaceMethodTypeDescription 
*)pMemberDescr)->nParams,
+                ((typelib_InterfaceMethodTypeDescription 
*)pMemberDescr)->pParams,
+                pReturn, pArgs, ppException );
+        }
+        break;
+    }
+    default:
+    {
+        ::com::sun::star::uno::RuntimeException aExc(
+            OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type 
description!") ),
+            ::com::sun::star::uno::Reference< 
::com::sun::star::uno::XInterface >() );
+        
+        Type const & rExcType = ::getCppuType( &aExc );
+        // binary identical null reference
+        ::uno_type_any_construct( *ppException, &aExc, 
rExcType.getTypeLibType(), 0 );
+    }
+    }
+}
+
+} } }
+
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/main/set_soenv.in b/main/set_soenv.in
index 0b19acb..b51f60b 100644
--- a/main/set_soenv.in
+++ b/main/set_soenv.in
@@ -397,6 +397,17 @@ elsif ( $platform =~ m/freebsd/ )
       $JRETOOLKITDIR  = 
'$JAVA_HOME'.$ds."jre".$ds."lib".$ds."i386".$ds."client";
       $JRETHREADDIR   = 
'$JAVA_HOME'.$ds."jre".$ds."lib".$ds."i386".$ds."native_threads";
    }
+   elsif ($platform =~ m/^arm.*?l-/)
+   {  print "Setting FreeBSD ARM specific values... ";
+      $outfile        = "FreeBSDARMEnv.Set"; 
+      $CPU            = "R";
+      $CPUNAME        = "ARM";
+      $OUTPATH        = "unxfbsdr";
+      $JRELIBDIR      = '$JAVA_HOME'.$ds."jre".$ds."lib".$ds."arm";
+      $JRETOOLKITDIR  = 
'$JAVA_HOME'.$ds."jre".$ds."lib".$ds."arm".$ds."server";
+      $JRETHREADDIR   = 
'$JAVA_HOME'.$ds."jre".$ds."lib".$ds."arm".$ds."native_threads";
+      $EPM_FLAGS      = "-a arm";
+   }
    elsif ($platform =~ m/^powerpc/)
    {
       if (($platform =~ m/^powerpc64/) && ('@SIZEOF_LONG@' eq '8')) {
diff --git a/main/solenv/inc/unxfbsd.mk b/main/solenv/inc/unxfbsd.mk
index 1955f17..006b815 100644
--- a/main/solenv/inc/unxfbsd.mk
+++ b/main/solenv/inc/unxfbsd.mk
@@ -46,6 +46,9 @@ JAVAFLAGSDEBUG=-g
 .IF "$(CPUNAME)" == "POWERPC64"
 .INCLUDE : unxfbsdppc64.mk
 .ENDIF
+.IF "$(CPUNAME)" == "ARM"
+.INCLUDE : unxfbsdr.mk
+.ENDIF
 
 # filter for supressing verbose messages from linker
 #not needed at the moment
diff --git a/main/solenv/inc/unxfbsdr.mk b/main/solenv/inc/unxfbsdr.mk
new file mode 100644
index 0000000..24cf868
--- /dev/null
+++ b/main/solenv/inc/unxfbsdr.mk
@@ -0,0 +1,46 @@
+#**************************************************************
+#  
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#  
+#    http://www.apache.org/licenses/LICENSE-2.0
+#  
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#  
+#**************************************************************
+
+
+
+# mk file for FreeBSD Unix ARM using GCC, please make generic modifications
+# to unxfbsd.mk
+
+CDEFAULTOPT=-Os
+CDEFS+=-DARM32
+CFLAGS+=-fno-omit-frame-pointer
+DLLPOSTFIX=
+
+.IF "$(ARM_TARGET)" == "ARMV4T"
+ARCH_FLAGS+=-march=armv4t
+CDEFS+=-DARMV4T
+.ENDIF
+
+.IF "$(ARM_TARGET)" == "ARMV6"
+ARCH_FLAGS+=-march=armv6
+CDEFS+=-DARMV6
+.ENDIF
+
+.IF "$(ARM_TARGET)" == "ARMV7"
+ARCH_FLAGS+=-march=armv7-a -mtune=cortex-a8 -mfpu=neon
+CDEFS+=-DARMV7
+.ENDIF
+

Reply via email to