/**************************************************************
 * 
 * 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.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_bridges.hxx"

#if defined OS2
#define INCL_DOS
#define INCL_DOSMISC
#endif

#include "bridges/cpp_uno/shared/vtablefactory.hxx"

#include "guardedarray.hxx"

#include "bridges/cpp_uno/shared/vtables.hxx"

#include "osl/thread.h"
#include "osl/security.hxx"
#include "osl/file.hxx"
#include "osl/diagnose.h"
#include "osl/mutex.hxx"
#include "rtl/alloc.h"
#include "rtl/ustring.hxx"
#include "sal/types.h"
#include "typelib/typedescription.hxx"

#include <hash_map>
#include <new>
#include <vector>

#if defined SAL_UNX
#include <unistd.h>
#include <string.h>
#include <sys/mman.h>
#elif defined SAL_W32
#define WIN32_LEAN_AND_MEAN
#ifdef _MSC_VER
#pragma warning(push,1) // disable warnings within system headers
#endif
#include <windows.h>
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#elif defined SAL_OS2
#define INCL_DOS
#define INCL_DOSMISC
#include <os2.h>
#else
#error Unsupported platform
#endif

using bridges::cpp_uno::shared::VtableFactory;

namespace {

extern "C" void * SAL_CALL allocExec(rtl_arena_type *, sal_Size * size) {
    sal_Size pagesize;
#if defined SAL_UNX
#if defined FREEBSD || defined NETBSD
    pagesize = getpagesize();
#else
    pagesize = sysconf(_SC_PAGESIZE);
#endif
#elif defined SAL_W32
    SYSTEM_INFO info;
    GetSystemInfo(&info);
    pagesize = info.dwPageSize;
#elif defined(SAL_OS2)
	ULONG ulPageSize;
	DosQuerySysInfo(QSV_PAGE_SIZE, QSV_PAGE_SIZE, &ulPageSize, sizeof(ULONG));
	pagesize = (sal_Size)ulPageSize;
#else
#error Unsupported platform
#endif
    sal_Size n = (*size + (pagesize - 1)) & ~(pagesize - 1);
    void * p;
#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;
	}
#elif defined SAL_W32
    p = VirtualAlloc(0, n, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
#elif defined(SAL_OS2)
    p = 0;
    DosAllocMem( &p, n, PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_ANY);
#endif
    if (p != 0) {
        *size = n;
    }
    return p;
}

extern "C" void SAL_CALL freeExec(
    rtl_arena_type *, void * address, sal_Size size)
{
#if defined SAL_UNX
    munmap(static_cast< char * >(address), size);
#elif defined SAL_W32
    (void) size; // unused
    VirtualFree(address, 0, MEM_RELEASE);
#elif defined(SAL_OS2)
	(void) DosFreeMem( address);
#endif
}

}

class VtableFactory::GuardedBlocks: public std::vector< Block > {
public:
    GuardedBlocks(VtableFactory const & factory):
        m_factory(factory), m_guarded(true) {}

    ~GuardedBlocks();

    void unguard() { m_guarded = false; }

private:
    GuardedBlocks(GuardedBlocks &); // not implemented
    void operator =(GuardedBlocks); // not implemented

    VtableFactory const & m_factory;
    bool m_guarded;
};

VtableFactory::GuardedBlocks::~GuardedBlocks() {
    if (m_guarded) {
        for (iterator i(begin()); i != end(); ++i) {
            m_factory.freeBlock(*i);
        }
    }
}

class VtableFactory::BaseOffset {
public:
    BaseOffset(typelib_InterfaceTypeDescription * type) { calculate(type, 0); }

    sal_Int32 getFunctionOffset(rtl::OUString const & name) const
    { return m_map.find(name)->second; }

private:
    sal_Int32 calculate(
        typelib_InterfaceTypeDescription * type, sal_Int32 offset);

    typedef std::hash_map< rtl::OUString, sal_Int32, rtl::OUStringHash > Map;

    Map m_map;
};

sal_Int32 VtableFactory::BaseOffset::calculate(
    typelib_InterfaceTypeDescription * type, sal_Int32 offset)
{
    rtl::OUString name(type->aBase.pTypeName);
    if (m_map.find(name) == m_map.end()) {
        for (sal_Int32 i = 0; i < type->nBaseTypes; ++i) {
            offset = calculate(type->ppBaseTypes[i], offset);
        }
        m_map.insert(Map::value_type(name, offset));
        typelib_typedescription_complete(
            reinterpret_cast< typelib_TypeDescription ** >(&type));
        offset += bridges::cpp_uno::shared::getLocalFunctions(type);
    }
    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))
{
    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(
    typelib_InterfaceTypeDescription * type)
{
    rtl::OUString name(type->aBase.pTypeName);
    osl::MutexGuard guard(m_mutex);
    Map::iterator i(m_map.find(name));
    if (i == m_map.end()) {
        GuardedBlocks blocks(*this);
        createVtables(blocks, BaseOffset(type), type, true);
        Vtables vtables;
        OSL_ASSERT(blocks.size() <= SAL_MAX_INT32);
        vtables.count = static_cast< sal_Int32 >(blocks.size());
        bridges::cpp_uno::shared::GuardedArray< Block > guardedBlocks(
            new Block[vtables.count]);
        vtables.blocks = guardedBlocks.get();
        for (sal_Int32 j = 0; j < vtables.count; ++j) {
            vtables.blocks[j] = blocks[j];
        }
        i = m_map.insert(Map::value_type(name, vtables)).first;
        guardedBlocks.release();
        blocks.unguard();
    }
    return i->second;
}

#ifdef USE_DOUBLE_MMAP
bool VtableFactory::createBlock(Block &block, sal_Int32 slotCount) const
{
    sal_Size size = getBlockSize(slotCount);
    sal_Size pagesize = sysconf(_SC_PAGESIZE);
    block.size = (size + (pagesize - 1)) & ~(pagesize - 1);
    block.start = block.exec = NULL;
    block.fd = -1;

    osl::Security aSecurity;
    rtl::OUString strDirectory;
    rtl::OUString strURLDirectory;
    if (aSecurity.getHomeDir(strURLDirectory))
        osl::File::getSystemPathFromFileURL(strURLDirectory, strDirectory);

    for (int i = strDirectory.isEmpty() ? 1 : 0; i < 2; ++i)
    {
        if (strDirectory.isEmpty())
            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 ((block.fd = mkstemp(tmpfname)) == -1)
            perror("creation of executable memory area failed");
        if (block.fd == -1)
        {
            delete[] tmpfname;
            break;
        }
        unlink(tmpfname);
        delete[] tmpfname;
        if (ftruncate(block.fd, block.size) == -1)
        {
            perror("truncation of executable memory area failed");
            close(block.fd);
            block.fd = -1;
            break;
        }
        block.start = mmap(NULL, block.size, PROT_READ | PROT_WRITE, MAP_SHARED, block.fd, 0);
        if (block.start== MAP_FAILED) {
            block.start = 0;
        }
        block.exec = mmap(NULL, block.size, PROT_READ | PROT_EXEC, MAP_SHARED, block.fd, 0);
        if (block.exec == MAP_FAILED) {
           block.exec = 0;
        }

        //All good
        if (block.start && block.exec && block.fd != -1)
            break;

        freeBlock(block);

        strDirectory = rtl::OUString();
    }
    if (!block.start || !block.exec || block.fd == -1)
    {
       //Fall back to non-doublemmaped allocation
       block.fd = -1;
       block.start = block.exec = rtl_arena_alloc(m_arena, &block.size);
    }
    return (block.start != 0 && block.exec != 0);
}

void VtableFactory::freeBlock(Block const & block) const {
    //if the double-map failed we were allocated on the arena
    if (block.fd == -1 && block.start == block.exec && block.start != NULL)
        rtl_arena_free(m_arena, block.start, block.size);
    else
    {
        if (block.start) munmap(block.start, block.size);
        if (block.exec) munmap(block.exec, block.size);
        if (block.fd != -1) close(block.fd);
    }
}
#else
bool VtableFactory::createBlock(Block &block, sal_Int32 slotCount) const
{
    block.size = getBlockSize(slotCount);
    block.start = rtl_arena_alloc(m_arena, &block.size);
    return block.start != 0;
}

void VtableFactory::freeBlock(Block const & block) const {
    rtl_arena_free(m_arena, block.start, block.size);
}
#endif

void VtableFactory::createVtables(
    GuardedBlocks & blocks, BaseOffset const & baseOffset,
    typelib_InterfaceTypeDescription * type, bool includePrimary) const
{
    if (includePrimary) {
        sal_Int32 slotCount
            = bridges::cpp_uno::shared::getPrimaryFunctions(type);
        Block block;
        if (!createBlock(block, slotCount)) {
            throw std::bad_alloc();
        }
        try {
            Slot * slots = initializeBlock(block.start, slotCount);
            unsigned char * codeBegin =
                reinterpret_cast< unsigned char * >(slots);
            unsigned char * code = codeBegin;
            sal_Int32 vtableOffset = blocks.size() * sizeof (Slot *);
            for (typelib_InterfaceTypeDescription const * type2 = type;
                 type2 != 0; type2 = type2->pBaseTypeDescription)
            {
                code = addLocalFunctions(
                    &slots, code,
#ifdef USE_DOUBLE_MMAP
                    sal_IntPtr(block.exec) - sal_IntPtr(block.start),
#endif
                    type2,
                    baseOffset.getFunctionOffset(type2->aBase.pTypeName),
                    bridges::cpp_uno::shared::getLocalFunctions(type2),
                    vtableOffset);
            }
            flushCode(codeBegin, code);
#ifdef USE_DOUBLE_MMAP
	    //Finished generating block, swap writable pointer with executable
	    //pointer
            ::std::swap(block.start, block.exec);
#endif
            blocks.push_back(block);
        } catch (...) {
            freeBlock(block);
            throw;
        }
    }
    for (sal_Int32 i = 0; i < type->nBaseTypes; ++i) {
        createVtables(blocks, baseOffset, type->ppBaseTypes[i], i != 0);
    }
}
