xpcom/reflect/xptcall/src/md/unix/xptcinvoke_arm_netbsd.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 /* Platform specific code to invoke XPCOM methods on native objects */
     8 #include "xptcprivate.h"
    10 // Remember that these 'words' are 32bit DWORDS
    12 static uint32_t
    13 invoke_count_words(uint32_t paramCount, nsXPTCVariant* s)
    14 {
    15     uint32_t result = 0;
    16     for(uint32_t i = 0; i < paramCount; i++, s++)
    17     {
    18         if(s->IsPtrData())
    19         {
    20             result++;
    21             continue;
    22         }
    23         switch(s->type)
    24         {
    25         case nsXPTType::T_I8     :
    26         case nsXPTType::T_I16    :
    27         case nsXPTType::T_I32    :
    28             result++;
    29             break;
    30         case nsXPTType::T_I64    :
    31             result+=2;
    32             break;
    33         case nsXPTType::T_U8     :
    34         case nsXPTType::T_U16    :
    35         case nsXPTType::T_U32    :
    36             result++;
    37             break;
    38         case nsXPTType::T_U64    :
    39             result+=2;
    40             break;
    41         case nsXPTType::T_FLOAT  :
    42             result++;
    43             break;
    44         case nsXPTType::T_DOUBLE :
    45             result+=2;
    46             break;
    47         case nsXPTType::T_BOOL   :
    48         case nsXPTType::T_CHAR   :
    49         case nsXPTType::T_WCHAR  :
    50             result++;
    51             break;
    52         default:
    53             // all the others are plain pointer types
    54             result++;
    55             break;
    56         }
    57     }
    58     return result;
    59 }
    61 static void
    62 invoke_copy_to_stack(uint32_t* d, uint32_t paramCount, nsXPTCVariant* s)
    63 {
    64     for(uint32_t i = 0; i < paramCount; i++, d++, s++)
    65     {
    66         if(s->IsPtrData())
    67         {
    68             *((void**)d) = s->ptr;
    69             continue;
    70         }
    71         switch(s->type)
    72         {
    73         case nsXPTType::T_I8     : *((int8_t*)  d) = s->val.i8;          break;
    74         case nsXPTType::T_I16    : *((int16_t*) d) = s->val.i16;         break;
    75         case nsXPTType::T_I32    : *((int32_t*) d) = s->val.i32;         break;
    76         case nsXPTType::T_I64    : *((int64_t*) d) = s->val.i64; d++;    break;
    77         case nsXPTType::T_U8     : *((uint8_t*) d) = s->val.u8;          break;
    78         case nsXPTType::T_U16    : *((uint16_t*)d) = s->val.u16;         break;
    79         case nsXPTType::T_U32    : *((uint32_t*)d) = s->val.u32;         break;
    80         case nsXPTType::T_U64    : *((uint64_t*)d) = s->val.u64; d++;    break;
    81         case nsXPTType::T_FLOAT  : *((float*)   d) = s->val.f;           break;
    82         case nsXPTType::T_DOUBLE : *((double*)  d) = s->val.d;   d++;    break;
    83         case nsXPTType::T_BOOL   : *((bool*)  d) = s->val.b;           break;
    84         case nsXPTType::T_CHAR   : *((char*)    d) = s->val.c;           break;
    85         case nsXPTType::T_WCHAR  : *((wchar_t*) d) = s->val.wc;          break;
    86         default:
    87             // all the others are plain pointer types
    88             *((void**)d) = s->val.p;
    89             break;
    90         }
    91     }
    92 }
    94 extern "C" 
    95 struct my_params_struct {
    96     nsISupports* that;      
    97     uint32_t Index;         
    98     uint32_t Count;         
    99     nsXPTCVariant* params;  
   100     uint32_t fn_count;     
   101     uint32_t fn_copy;      
   102 };
   104 XPTC_PUBLIC_API(nsresult)
   105 XPTC_InvokeByIndex(nsISupports* that, uint32_t methodIndex,
   106                    uint32_t paramCount, nsXPTCVariant* params)
   107 {
   108     uint32_t result;
   109     struct my_params_struct my_params;
   110     my_params.that = that;
   111     my_params.Index = methodIndex;
   112     my_params.Count = paramCount;
   113     my_params.params = params;
   114     my_params.fn_copy = (uint32_t) &invoke_copy_to_stack;
   115     my_params.fn_count = (uint32_t) &invoke_count_words;
   117 /* This is to call a given method of class that.
   118  * The parameters are in params, the number is in paramCount.
   119  * The routine will issue calls to count the number of words
   120  * required for argument passing and to copy the arguments to
   121  * the stack.
   122  * Since APCS passes the first 3 params in r1-r3, we need to
   123  * load the first three words from the stack and correct the stack
   124  * pointer (sp) in the appropriate way. This means:
   125  *
   126  * 1.) more than 3 arguments: load r1-r3, correct sp and remember No.
   127  *			      of bytes left on the stack in r4
   128  *
   129  * 2.) <= 2 args: load r1-r3 (we won't be causing a stack overflow I hope),
   130  *		  restore sp as if nothing had happened and set the marker r4 to zero.
   131  *
   132  * Afterwards sp will be restored using the value in r4 (which is not a temporary register
   133  * and will be preserved by the function/method called according to APCS [ARM Procedure
   134  * Calling Standard]).
   135  *
   136  * !!! IMPORTANT !!!
   137  * This routine makes assumptions about the vtable layout of the c++ compiler. It's implemented
   138  * for arm-linux GNU g++ >= 2.8.1 (including egcs and gcc-2.95.[1-3])!
   139  *
   140  */
   142   __asm__ __volatile__(
   143     "ldr	r1, [%1, #12]	\n\t"	/* prepare to call invoke_count_words	*/
   144     "ldr	ip, [%1, #16]	\n\t"	/* r0=paramCount, r1=params		*/
   145     "ldr	r0, [%1,  #8]	\n\t"
   146     "mov	lr, pc		\n\t"	/* call it...				*/
   147     "mov	pc, ip		\n\t"
   148     "mov	r4, r0, lsl #2	\n\t"	/* This is the amount of bytes needed.	*/
   149     "sub	sp, sp, r4	\n\t"	/* use stack space for the args...	*/
   150     "mov	r0, sp		\n\t"	/* prepare a pointer an the stack	*/
   151     "ldr	r1, [%1,  #8]	\n\t"	/* =paramCount				*/
   152     "ldr	r2, [%1, #12]	\n\t"	/* =params				*/
   153     "ldr	ip, [%1, #20]	\n\t"	/* =invoke_copy_to_stack		*/
   154     "mov	lr, pc		\n\t"	/* copy args to the stack like the	*/
   155     "mov	pc, ip		\n\t"	/* compiler would.			*/
   156     "ldr	r0, [%1]	\n\t"	/* =that				*/
   157     "ldr	r1, [r0, #0]	\n\t"	/* get that->vtable offset		*/
   158     "ldr	r2, [%1, #4]	\n\t"
   159     "add	r2, r1, r2, lsl #3\n\t"	/* a vtable_entry(x)=8 + (8 bytes * x)	*/
   160     "add	r2, r2, #8	\n\t"	/* with this compilers			*/
   161     "ldr	r3, [r2]	\n\t"	/* get virtual offset from vtable	*/
   162     "mov	r3, r3, lsl #16	\n\t"
   163     "add	r0, r0, r3, asr #16\n\t"
   164     "ldr	ip, [r2, #4]	\n\t"	/* get method address from vtable	*/
   165     "cmp	r4, #12		\n\t"	/* more than 3 arguments???		*/
   166     "ldmgtia	sp!, {r1, r2, r3}\n\t"	/* yes: load arguments for r1-r3	*/
   167     "subgt	r4, r4, #12	\n\t"	/*      and correct the stack pointer	*/
   168     "ldmleia	sp, {r1, r2, r3}\n\t"	/* no:  load r1-r3 from stack		*/ 
   169     "addle	sp, sp, r4	\n\t"	/*      and restore stack pointer	*/
   170     "movle	r4, #0		\n\t"	/*	a mark for restoring sp		*/
   171     "mov	lr, pc		\n\t"	/* call mathod				*/
   172     "mov	pc, ip		\n\t"
   173     "add	sp, sp, r4	\n\t"	/* restore stack pointer		*/
   174     "mov	%0, r0		\n\t"	/* the result...			*/
   175     : "=r" (result)
   176     : "r" (&my_params)
   177     : "r0", "r1", "r2", "r3", "r4", "ip", "lr"
   178     );
   180   return result;
   181 }    

mercurial