xpcom/reflect/xptcall/src/md/unix/xptcstubs_arm.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 /* Implement shared vtbl methods. */
     8 #include "xptcprivate.h"
     9 #include "xptiprivate.h"
    11 #if !defined(__arm__) && !(defined(LINUX) || defined(ANDROID))
    12 #error "This code is for Linux ARM only. Please check if it works for you, too.\nDepends strongly on gcc behaviour."
    13 #endif
    15 /* Specify explicitly a symbol for this function, don't try to guess the c++ mangled symbol.  */
    16 static nsresult PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint32_t* args) asm("_PrepareAndDispatch")
    17 ATTRIBUTE_USED;
    19 #ifdef __ARM_EABI__
    20 #define DOUBLEWORD_ALIGN(p) ((uint32_t *)((((uint32_t)(p)) + 7) & 0xfffffff8))
    21 #else
    22 #define DOUBLEWORD_ALIGN(p) (p)
    23 #endif
    25 // Apple's iOS toolchain is lame and does not support .cfi directives.
    26 #ifdef __APPLE__
    27 #define CFI(str)
    28 #else
    29 #define CFI(str) str
    30 #endif
    32 static nsresult
    33 PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint32_t* args)
    34 {
    35 #define PARAM_BUFFER_COUNT     16
    37     nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
    38     nsXPTCMiniVariant* dispatchParams = nullptr;
    39     const nsXPTMethodInfo* info;
    40     uint8_t paramCount;
    41     uint8_t i;
    42     nsresult result = NS_ERROR_FAILURE;
    44     NS_ASSERTION(self,"no self");
    46     self->mEntry->GetMethodInfo(uint16_t(methodIndex), &info);
    47     paramCount = info->GetParamCount();
    49     // setup variant array pointer
    50     if(paramCount > PARAM_BUFFER_COUNT)
    51         dispatchParams = new nsXPTCMiniVariant[paramCount];
    52     else
    53         dispatchParams = paramBuffer;
    54     NS_ASSERTION(dispatchParams,"no place for params");
    56     uint32_t* ap = args;
    57     for(i = 0; i < paramCount; i++, ap++)
    58     {
    59         const nsXPTParamInfo& param = info->GetParam(i);
    60         const nsXPTType& type = param.GetType();
    61         nsXPTCMiniVariant* dp = &dispatchParams[i];
    63         if(param.IsOut() || !type.IsArithmetic())
    64         {
    65             dp->val.p = (void*) *ap;
    66             continue;
    67         }
    68         // else
    69         switch(type)
    70         {
    71         case nsXPTType::T_I8     : dp->val.i8  = *((int8_t*)  ap);       break;
    72         case nsXPTType::T_I16    : dp->val.i16 = *((int16_t*) ap);       break;
    73         case nsXPTType::T_I32    : dp->val.i32 = *((int32_t*) ap);       break;
    74         case nsXPTType::T_I64    : ap = DOUBLEWORD_ALIGN(ap);
    75 				   dp->val.i64 = *((int64_t*) ap); ap++; break;
    76         case nsXPTType::T_U8     : dp->val.u8  = *((uint8_t*) ap);       break;
    77         case nsXPTType::T_U16    : dp->val.u16 = *((uint16_t*)ap);       break;
    78         case nsXPTType::T_U32    : dp->val.u32 = *((uint32_t*)ap);       break;
    79         case nsXPTType::T_U64    : ap = DOUBLEWORD_ALIGN(ap);
    80 				   dp->val.u64 = *((uint64_t*)ap); ap++; break;
    81         case nsXPTType::T_FLOAT  : dp->val.f   = *((float*)   ap);       break;
    82         case nsXPTType::T_DOUBLE : ap = DOUBLEWORD_ALIGN(ap);
    83 				   dp->val.d   = *((double*)  ap); ap++; break;
    84         case nsXPTType::T_BOOL   : dp->val.b   = *((bool*)  ap);       break;
    85         case nsXPTType::T_CHAR   : dp->val.c   = *((char*)    ap);       break;
    86         case nsXPTType::T_WCHAR  : dp->val.wc  = *((wchar_t*) ap);       break;
    87         default:
    88             NS_ERROR("bad type");
    89             break;
    90         }
    91     }
    93     result = self->mOuter->CallMethod((uint16_t)methodIndex, info, dispatchParams);
    95     if(dispatchParams != paramBuffer)
    96         delete [] dispatchParams;
    98     return result;
    99 }
   101 /*
   102  * This is our shared stub.
   103  *
   104  * r0 = Self.
   105  *
   106  * The Rules:
   107  *   We pass an (undefined) number of arguments into this function.
   108  *   The first 3 C++ arguments are in r1 - r3, the rest are built
   109  *   by the calling function on the stack.
   110  *
   111  *   We are allowed to corrupt r0 - r3, ip, and lr.
   112  *
   113  * Other Info:
   114  *   We pass the stub number in using `ip'.
   115  *
   116  * Implementation:
   117  * - We save r1 to r3 inclusive onto the stack, which will be
   118  *   immediately below the caller saved arguments.
   119  * - setup r2 (PrepareAndDispatch's args pointer) to point at
   120  *   the base of all these arguments
   121  * - Save LR (for the return address)
   122  * - Set r1 (PrepareAndDispatch's methodindex argument) from ip
   123  * - r0 is passed through (self)
   124  * - Call PrepareAndDispatch
   125  * - When the call returns, we return by loading the PC off the
   126  *   stack, and undoing the stack (one instruction)!
   127  *
   128  */
   129 __asm__ ("\n"
   130          ".text\n"
   131          ".align 2\n"
   132          "SharedStub:\n"
   133          ".fnstart\n"
   134          CFI(".cfi_startproc\n")
   135          "stmfd	sp!, {r1, r2, r3}\n"
   136          ".save	{r1, r2, r3}\n"
   137          CFI(".cfi_def_cfa_offset 12\n")
   138          CFI(".cfi_offset r3, -4\n")
   139          CFI(".cfi_offset r2, -8\n")
   140          CFI(".cfi_offset r1, -12\n")
   141          "mov	r2, sp\n"
   142          "str	lr, [sp, #-4]!\n"
   143          ".save	{lr}\n"
   144          CFI(".cfi_def_cfa_offset 16\n")
   145          CFI(".cfi_offset lr, -16\n")
   146          "mov	r1, ip\n"
   147          "bl	_PrepareAndDispatch\n"
   148          "ldr	pc, [sp], #16\n"
   149          CFI(".cfi_endproc\n")
   150          ".fnend");
   152 /*
   153  * Create sets of stubs to call the SharedStub.
   154  * We don't touch the stack here, nor any registers, other than IP.
   155  * IP is defined to be corruptable by a called function, so we are
   156  * safe to use it.
   157  *
   158  * This will work with or without optimisation.
   159  */
   161 /*
   162  * Note : As G++3 ABI contains the length of the functionname in the
   163  *  mangled name, it is difficult to get a generic assembler mechanism like
   164  *  in the G++ 2.95 case.
   165  *  Create names would be like :
   166  *    _ZN14nsXPTCStubBase5Stub9Ev
   167  *    _ZN14nsXPTCStubBase6Stub13Ev
   168  *    _ZN14nsXPTCStubBase7Stub144Ev
   169  *  Use the assembler directives to get the names right...
   170  */
   172 #define STUB_ENTRY(n)						\
   173   __asm__(							\
   174 	".section \".text\"\n"					\
   175 "	.align 2\n"						\
   176 "	.iflt ("#n" - 10)\n"                                    \
   177 "	.globl	_ZN14nsXPTCStubBase5Stub"#n"Ev\n"		\
   178 "	.type	_ZN14nsXPTCStubBase5Stub"#n"Ev,#function\n"	\
   179 "_ZN14nsXPTCStubBase5Stub"#n"Ev:\n"				\
   180 "	.else\n"                                                \
   181 "	.iflt  ("#n" - 100)\n"                                  \
   182 "	.globl	_ZN14nsXPTCStubBase6Stub"#n"Ev\n"		\
   183 "	.type	_ZN14nsXPTCStubBase6Stub"#n"Ev,#function\n"	\
   184 "_ZN14nsXPTCStubBase6Stub"#n"Ev:\n"				\
   185 "	.else\n"                                                \
   186 "	.iflt ("#n" - 1000)\n"                                  \
   187 "	.globl	_ZN14nsXPTCStubBase7Stub"#n"Ev\n"		\
   188 "	.type	_ZN14nsXPTCStubBase7Stub"#n"Ev,#function\n"	\
   189 "_ZN14nsXPTCStubBase7Stub"#n"Ev:\n"				\
   190 "	.else\n"                                                \
   191 "	.err \"stub number "#n"> 1000 not yet supported\"\n"    \
   192 "	.endif\n"                                               \
   193 "	.endif\n"                                               \
   194 "	.endif\n"                                               \
   195 "	mov	ip, #"#n"\n"					\
   196 "	b	SharedStub\n\t");
   198 #if 0
   199 /*
   200  * This part is left in as comment : this is how the method definition
   201  * should look like.
   202  */
   204 #define STUB_ENTRY(n)  \
   205 nsresult nsXPTCStubBase::Stub##n ()  \
   206 { \
   207   __asm__ (	  		        \
   208 "	mov	ip, #"#n"\n"					\
   209 "	b	SharedStub\n\t");                               \
   210   return 0; /* avoid warnings */                                \
   211 }
   212 #endif
   215 #define SENTINEL_ENTRY(n) \
   216 nsresult nsXPTCStubBase::Sentinel##n() \
   217 { \
   218     NS_ERROR("nsXPTCStubBase::Sentinel called"); \
   219     return NS_ERROR_NOT_IMPLEMENTED; \
   220 }
   222 #include "xptcstubsdef.inc"

mercurial