diff options
Diffstat (limited to 'src/qml/jsruntime/qv4unwindhelper_arm_p.h')
-rw-r--r-- | src/qml/jsruntime/qv4unwindhelper_arm_p.h | 234 |
1 files changed, 0 insertions, 234 deletions
diff --git a/src/qml/jsruntime/qv4unwindhelper_arm_p.h b/src/qml/jsruntime/qv4unwindhelper_arm_p.h deleted file mode 100644 index e15dbb0f2b..0000000000 --- a/src/qml/jsruntime/qv4unwindhelper_arm_p.h +++ /dev/null @@ -1,234 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QV4UNWINDHELPER_ARM_P_H -#define QV4UNWINDHELPER_ARM_P_H - -#include "qv4unwindhelper_p.h" -#include "qv4functionobject_p.h" -#include "qv4function_p.h" -#include <wtf/Platform.h> - -#include <QMap> -#include <QMutex> - -#define __USE_GNU -#include <dlfcn.h> - -#if USE(LIBUNWIND_DEBUG) -#include <libunwind.h> -#include <execinfo.h> -#endif - -QT_BEGIN_NAMESPACE - -namespace QV4 { - -static void *removeThumbBit(void *addr) -{ - return reinterpret_cast<void*>(reinterpret_cast<qintptr>(addr) & ~1u); -} - -static QMutex functionProtector; -static QMap<quintptr, Function*> allFunctions; - -static Function *lookupFunction(void *pc) -{ - quintptr key = reinterpret_cast<quintptr>(pc); - QMap<quintptr, Function*>::Iterator it = allFunctions.lowerBound(key); - if (it != allFunctions.begin() && allFunctions.count() > 0) - --it; - if (it == allFunctions.end()) - return 0; - - quintptr codeStart = reinterpret_cast<quintptr>(removeThumbBit((void*)(*it)->codePtr)); - if (key < codeStart || key >= codeStart + (*it)->codeSize) - return 0; - return *it; -} - - -/* Program: -vsp = r4 (REG_TO_SP r4) -vsp -= 8 * 4 -- > vsp = vsp - (7 << 2) - 4 -pop r12, r10, r9, r8, r7, r6, r5, r4 -pop r4 -pop lr -pop r0, r1, r2, r3 -*/ - -#define REG_TO_SP ((unsigned int) 0b10010000) -#define VSP_MINUS ((unsigned int) 0b01000000) -#define POP_REG_MULTI ((unsigned int) 0b10000000) -#define POP_R4_MULTI ((unsigned int) 0b10100000) -#define POP_R4_R14_MULTI ((unsigned int) 0b10101000) -#define POP_R0_TO_R3 ((unsigned int) 0b10110001) -#define FINISH ((unsigned int) 0b10110000) - -#define MK_UW_WORD(first, second, third, fourth) \ - (((first) << 24) | \ - ((second) << 16) | \ - ((third) << 8) | \ - (fourth)) - -static unsigned int extbl[] = { - MK_UW_WORD(0x80 | // High bit set to indicate that this isn't a PREL31 - 2, // Choose personality routine #2 - 2, // Number of 4 byte words used to encode remaining unwind instructions - REG_TO_SP | 4, // Encoded program from above. - VSP_MINUS | 7), - MK_UW_WORD(POP_REG_MULTI | 1, 0b01111111, - POP_R4_R14_MULTI, - POP_R0_TO_R3), - MK_UW_WORD(0b00001111, - FINISH, - FINISH, - FINISH), - 0 // no additional entries -}; - -static unsigned write_prel31(unsigned *addr, void *ptr) -{ - int delta = (char *)ptr - (char*)addr; - if (delta < 0) - delta |= (1 << 30); - else - delta &= ~(1 << 30); - *addr = ((unsigned)delta) & 0x7fffffffU; -} - -void UnwindHelper::deregisterFunction(Function *function) -{ - QMutexLocker locker(&functionProtector); - allFunctions.remove(reinterpret_cast<quintptr>(function->codePtr)); -} - -void UnwindHelper::deregisterFunctions(const QVector<Function *> &functions) -{ - QMutexLocker locker(&functionProtector); - foreach (Function *f, functions) - allFunctions.remove(reinterpret_cast<quintptr>(f->codePtr)); -} - -void UnwindHelper::registerFunction(Function *function) -{ - QMutexLocker locker(&functionProtector); - allFunctions.insert(reinterpret_cast<quintptr>(function->codePtr), function); -} - -void UnwindHelper::registerFunctions(const QVector<Function *> &functions) -{ - QMutexLocker locker(&functionProtector); - foreach (Function *f, functions) - allFunctions.insert(reinterpret_cast<quintptr>(f->codePtr), f); -} - -void UnwindHelper::prepareForUnwind(ExecutionContext *) -{ -} - -int UnwindHelper::unwindInfoSize() -{ - return 2 * sizeof(unsigned int) // 2 extbl entries - + sizeof(extbl); -} - -void UnwindHelper::writeARMUnwindInfo(void *codeAddr, int codeSize) -{ - unsigned int *exidx = (unsigned int *)((char *)codeAddr + codeSize); - - unsigned char *exprog = (unsigned char *)((unsigned char *)codeAddr + codeSize + 8); - - write_prel31(exidx, codeAddr); - exidx[1] = 4; // PREL31 offset to extbl, which follows right afterwards - - memcpy(exprog, extbl, sizeof(extbl)); - -#if USE(LIBUNWIND_DEBUG) - unw_dyn_info_t *info = (unw_dyn_info_t*)malloc(sizeof(unw_dyn_info_t)); - info->start_ip = (unw_word_t)codeAddr; - info->end_ip = info->start_ip + codeSize; - info->gp = 0; - info->format = UNW_INFO_FORMAT_ARM_EXIDX; - info->u.rti.name_ptr = 0; - info->u.rti.segbase = 0; - info->u.rti.table_len = 8; - info->u.rti.table_data = (unw_word_t)exidx; - _U_dyn_register(info); -#endif -} - -} - -QT_END_NAMESPACE - -#if defined(Q_OS_ANDROID) -extern "C" void *dl_unwind_find_exidx(void *pc, int *entryCount); -#endif - -extern "C" Q_DECL_EXPORT void *__gnu_Unwind_Find_exidx(void *pc, int *entryCount) -{ -#if !defined(Q_OS_ANDROID) - typedef void *(*Old_Unwind_Find_exidx)(void*, int*); - static Old_Unwind_Find_exidx oldFunction = 0; - if (!oldFunction) - oldFunction = (Old_Unwind_Find_exidx)dlsym(RTLD_NEXT, "__gnu_Unwind_Find_exidx"); -#endif - - { - QMutexLocker locker(&QT_PREPEND_NAMESPACE(QV4::functionProtector)); - QV4::Function *function = QT_PREPEND_NAMESPACE(QV4::lookupFunction(pc)); - if (function) { - *entryCount = 1; - void * codeStart = QT_PREPEND_NAMESPACE(QV4::removeThumbBit((void*)function->codePtr)); - // At the end of the function we store our synthetic exception table entry. - return (char *)codeStart + function->codeSize; - } - } - -#if defined(Q_OS_ANDROID) - return dl_unwind_find_exidx(pc, entryCount); -#else - return oldFunction(pc, entryCount); -#endif -} - -#endif // QV4UNWINDHELPER_PDW2_H |