xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc_linux.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 // The Linux/PPC ABI (aka PPC/SYSV ABI) passes the first 8 integral
    12 // parameters and the first 8 floating point parameters in registers
    13 // (r3-r10 and f1-f8), no stack space is allocated for these by the
    14 // caller.  The rest of the parameters are passed in the callers stack
    15 // area. The stack pointer has to retain 16-byte alignment, longlongs
    16 // and doubles are aligned on 8-byte boundaries.
    17 #ifndef __NO_FPRS__
    18 #define PARAM_BUFFER_COUNT     16
    19 #define GPR_COUNT               8
    20 #define FPR_COUNT               8
    21 #else
    22 #define PARAM_BUFFER_COUNT      8
    23 #define GPR_COUNT               8
    24 #endif
    25 // PrepareAndDispatch() is called by SharedStub() and calls the actual method.
    26 //
    27 // - 'args[]' contains the arguments passed on stack
    28 // - 'gprData[]' contains the arguments passed in integer registers
    29 // - 'fprData[]' contains the arguments passed in floating point registers
    30 // 
    31 // The parameters are mapped into an array of type 'nsXPTCMiniVariant'
    32 // and then the method gets called.
    34 extern "C" nsresult ATTRIBUTE_USED
    35 PrepareAndDispatch(nsXPTCStubBase* self,
    36                    uint32_t methodIndex,
    37                    uint32_t* args,
    38                    uint32_t *gprData,
    39                    double *fprData)
    40 {
    41     nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
    42     nsXPTCMiniVariant* dispatchParams = nullptr;
    43     const nsXPTMethodInfo* info = nullptr;
    44     uint32_t paramCount;
    45     uint32_t i;
    46     nsresult result = NS_ERROR_FAILURE;
    48     NS_ASSERTION(self,"no self");
    50     self->mEntry->GetMethodInfo(uint16_t(methodIndex), &info);
    51     NS_ASSERTION(info,"no method info");
    52     if (! info)
    53         return NS_ERROR_UNEXPECTED;
    55     paramCount = info->GetParamCount();
    57     // setup variant array pointer
    58     if(paramCount > PARAM_BUFFER_COUNT)
    59         dispatchParams = new nsXPTCMiniVariant[paramCount];
    60     else
    61         dispatchParams = paramBuffer;
    63     NS_ASSERTION(dispatchParams,"no place for params");
    64     if (! dispatchParams)
    65         return NS_ERROR_OUT_OF_MEMORY;
    67     uint32_t* ap = args;
    68     uint32_t gpr = 1;    // skip one GPR register
    69 #ifndef __NO_FPRS__
    70     uint32_t fpr = 0;
    71 #endif
    72     uint32_t tempu32;
    73     uint64_t tempu64;
    75     for(i = 0; i < paramCount; i++) {
    76         const nsXPTParamInfo& param = info->GetParam(i);
    77         const nsXPTType& type = param.GetType();
    78         nsXPTCMiniVariant* dp = &dispatchParams[i];
    80         if (!param.IsOut() && type == nsXPTType::T_DOUBLE) {
    81 #ifndef __NO_FPRS__
    82             if (fpr < FPR_COUNT)
    83                 dp->val.d = fprData[fpr++];
    84 #else
    85             if (gpr & 1)
    86                 gpr++;
    87             if (gpr + 1 < GPR_COUNT) {
    88                 dp->val.d = *(double*) &gprData[gpr];
    89                 gpr += 2;
    90             }
    91 #endif
    92             else {
    93                 if ((uint32_t) ap & 4) ap++; // doubles are 8-byte aligned on stack
    94                 dp->val.d = *(double*) ap;
    95                 ap += 2;
    96             }
    97             continue;
    98         }
    99         else if (!param.IsOut() && type == nsXPTType::T_FLOAT) {
   100 #ifndef __NO_FPRS__
   101             if (fpr < FPR_COUNT)
   102                 dp->val.f = (float) fprData[fpr++]; // in registers floats are passed as doubles
   103 #else
   104             if (gpr  < GPR_COUNT)
   105                 dp->val.f = *(float*) &gprData[gpr++];
   106 #endif
   107             else
   108                 dp->val.f = *(float*) ap++;
   109             continue;
   110         }
   111         else if (!param.IsOut() && (type == nsXPTType::T_I64
   112                                     || type == nsXPTType::T_U64)) {
   113             if (gpr & 1) gpr++; // longlongs are aligned in odd/even register pairs, eg. r5/r6
   114             if ((gpr + 1) < GPR_COUNT) {
   115                 tempu64 = *(uint64_t*) &gprData[gpr];
   116                 gpr += 2;
   117             }
   118             else {
   119                 if ((uint32_t) ap & 4) ap++; // longlongs are 8-byte aligned on stack
   120                 tempu64 = *(uint64_t*) ap;
   121                 ap += 2;
   122             }
   123         }
   124         else {
   125             if (gpr < GPR_COUNT)
   126                 tempu32 = gprData[gpr++];
   127             else
   128                 tempu32 = *ap++;
   129         }
   131         if(param.IsOut() || !type.IsArithmetic()) {
   132             dp->val.p = (void*) tempu32;
   133             continue;
   134         }
   136         switch(type) {
   137         case nsXPTType::T_I8:      dp->val.i8  = (int8_t)   tempu32; break;
   138         case nsXPTType::T_I16:     dp->val.i16 = (int16_t)  tempu32; break;
   139         case nsXPTType::T_I32:     dp->val.i32 = (int32_t)  tempu32; break;
   140         case nsXPTType::T_I64:     dp->val.i64 = (int64_t)  tempu64; break;
   141         case nsXPTType::T_U8:      dp->val.u8  = (uint8_t)  tempu32; break;
   142         case nsXPTType::T_U16:     dp->val.u16 = (uint16_t) tempu32; break;
   143         case nsXPTType::T_U32:     dp->val.u32 = (uint32_t) tempu32; break;
   144         case nsXPTType::T_U64:     dp->val.u64 = (uint64_t) tempu64; break;
   145         case nsXPTType::T_BOOL:    dp->val.b   = (bool)   tempu32; break;
   146         case nsXPTType::T_CHAR:    dp->val.c   = (char)     tempu32; break;
   147         case nsXPTType::T_WCHAR:   dp->val.wc  = (wchar_t)  tempu32; break;
   149         default:
   150             NS_ERROR("bad type");
   151             break;
   152         }
   153     }
   155     result = self->mOuter->CallMethod((uint16_t)methodIndex,
   156                                       info,
   157                                       dispatchParams);
   159     if (dispatchParams != paramBuffer)
   160         delete [] dispatchParams;
   162     return result;
   163 }
   165 // Load r11 with the constant 'n' and branch to SharedStub().
   166 //
   167 // XXX Yes, it's ugly that we're relying on gcc's name-mangling here;
   168 // however, it's quick, dirty, and'll break when the ABI changes on
   169 // us, which is what we want ;-).
   171 // gcc-3 version
   172 //
   173 // As G++3 ABI contains the length of the functionname in the mangled
   174 // name, it is difficult to get a generic assembler mechanism like
   175 // in the G++ 2.95 case.
   176 // Create names would be like:
   177 // _ZN14nsXPTCStubBase5Stub1Ev
   178 // _ZN14nsXPTCStubBase6Stub12Ev
   179 // _ZN14nsXPTCStubBase7Stub123Ev
   180 // _ZN14nsXPTCStubBase8Stub1234Ev
   181 // etc.
   182 // Use assembler directives to get the names right...
   184 # define STUB_ENTRY(n)							\
   185 __asm__ (								\
   186 	".align	2 \n\t"							\
   187 	".if	"#n" < 10 \n\t"						\
   188 	".globl	_ZN14nsXPTCStubBase5Stub"#n"Ev \n\t"			\
   189 	".type	_ZN14nsXPTCStubBase5Stub"#n"Ev,@function \n\n"		\
   190 "_ZN14nsXPTCStubBase5Stub"#n"Ev: \n\t"					\
   191 									\
   192 	".elseif "#n" < 100 \n\t"					\
   193 	".globl	_ZN14nsXPTCStubBase6Stub"#n"Ev \n\t"			\
   194 	".type	_ZN14nsXPTCStubBase6Stub"#n"Ev,@function \n\n"		\
   195 "_ZN14nsXPTCStubBase6Stub"#n"Ev: \n\t"					\
   196 									\
   197 	".elseif "#n" < 1000 \n\t"					\
   198 	".globl	_ZN14nsXPTCStubBase7Stub"#n"Ev \n\t"			\
   199 	".type	_ZN14nsXPTCStubBase7Stub"#n"Ev,@function \n\n"		\
   200 "_ZN14nsXPTCStubBase7Stub"#n"Ev: \n\t"					\
   201 									\
   202 	".else \n\t"							\
   203 	".err	\"stub number "#n" >= 1000 not yet supported\"\n"	\
   204 	".endif \n\t"							\
   205 									\
   206 	"li	11,"#n" \n\t"						\
   207 	"b	SharedStub@local \n"					\
   208 );
   210 #define SENTINEL_ENTRY(n)                            \
   211 nsresult nsXPTCStubBase::Sentinel##n()               \
   212 {                                                    \
   213   NS_ERROR("nsXPTCStubBase::Sentinel called"); \
   214   return NS_ERROR_NOT_IMPLEMENTED;                   \
   215 }
   217 #include "xptcstubsdef.inc"

mercurial