Index: mozilla/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_arm.cpp =================================================================== --- mozilla.orig/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_arm.cpp 2009-06-25 11:12:00.000000000 -0400 +++ mozilla/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_arm.cpp 2009-06-25 11:32:55.000000000 -0400 @@ -43,6 +43,17 @@ #error "This code is for Linux ARM only. Check that it works on your system, too.\nBeware that this code is highly compiler dependent." #endif +/* Note that we give a "worst case" estimate of how much stack _might_ be +* needed (for __ARM_EABI__), rather than the real count - this should be safe */ + +#ifdef __ARM_EABI__ +#define DOUBLEWORD_ALIGN(p) ((PRUint32 *)((((PRUint32)(p)) + 7) & 0xfffffff8)) +#define VAR_STACK_SIZE_64 3 +#else +#define DOUBLEWORD_ALIGN(p) (p) +#define VAR_STACK_SIZE_64 2 +#endif + // Remember that these 'words' are 32bit DWORDS static PRUint32 @@ -64,7 +75,7 @@ result++; break; case nsXPTType::T_I64 : - result+=2; + result+=VAR_STACK_SIZE_64; break; case nsXPTType::T_U8 : case nsXPTType::T_U16 : @@ -72,13 +83,13 @@ result++; break; case nsXPTType::T_U64 : - result+=2; + result+=VAR_STACK_SIZE_64 ; break; case nsXPTType::T_FLOAT : result++; break; case nsXPTType::T_DOUBLE : - result+=2; + result+=VAR_STACK_SIZE_64 ; break; case nsXPTType::T_BOOL : case nsXPTType::T_CHAR : @@ -91,6 +102,15 @@ break; } } + +#ifdef __ARM_EABI__ + /* Ensure stack is always aligned to doubleword boundary; we take 3 words + * off the stack to r1-r3 later, so it must always be on _odd_ word + * boundary after this */ + if (result % 2 == 0) + result++; +#endif + return result; } @@ -109,13 +129,16 @@ case nsXPTType::T_I8 : *((PRInt8*) d) = s->val.i8; break; case nsXPTType::T_I16 : *((PRInt16*) d) = s->val.i16; break; case nsXPTType::T_I32 : *((PRInt32*) d) = s->val.i32; break; - case nsXPTType::T_I64 : *((PRInt64*) d) = s->val.i64; d++; break; + case nsXPTType::T_I64 : d = DOUBLEWORD_ALIGN(d); + *((PRInt64*) d) = s->val.i64; d++; break; case nsXPTType::T_U8 : *((PRUint8*) d) = s->val.u8; break; case nsXPTType::T_U16 : *((PRUint16*)d) = s->val.u16; break; case nsXPTType::T_U32 : *((PRUint32*)d) = s->val.u32; break; - case nsXPTType::T_U64 : *((PRUint64*)d) = s->val.u64; d++; break; + case nsXPTType::T_U64 : d = DOUBLEWORD_ALIGN(d); + *((PRUint64*)d) = s->val.u64; d++; break; case nsXPTType::T_FLOAT : *((float*) d) = s->val.f; break; - case nsXPTType::T_DOUBLE : *((double*) d) = s->val.d; d++; break; + case nsXPTType::T_DOUBLE : d = DOUBLEWORD_ALIGN(d); + *((double*) d) = s->val.d; d++; break; case nsXPTType::T_BOOL : *((PRBool*) d) = s->val.b; break; case nsXPTType::T_CHAR : *((char*) d) = s->val.c; break; case nsXPTType::T_WCHAR : *((wchar_t*) d) = s->val.wc; break;