Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | # This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 2 | # License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/. |
michael@0 | 4 | |
michael@0 | 5 | .set r0,0; .set r1,1; .set r2,2; .set r3,3; .set r4,4 |
michael@0 | 6 | .set r5,5; .set r6,6; .set r7,7; .set r8,8; .set r9,9 |
michael@0 | 7 | .set r10,10; .set r11,11; .set r12,12; .set r13,13; .set r14,14 |
michael@0 | 8 | .set r15,15; .set r16,16; .set r17,17; .set r18,18; .set r19,19 |
michael@0 | 9 | .set r20,20; .set r21,21; .set r22,22; .set r23,23; .set r24,24 |
michael@0 | 10 | .set r25,25; .set r26,26; .set r27,27; .set r28,28; .set r29,29 |
michael@0 | 11 | .set r30,30; .set r31,31 |
michael@0 | 12 | .set f0,0; .set f1,1; .set f2,2; .set f3,3; .set f4,4 |
michael@0 | 13 | .set f5,5; .set f6,6; .set f7,7; .set f8,8; .set f9,9 |
michael@0 | 14 | .set f10,10; .set f11,11; .set f12,12; .set f13,13; .set f14,14 |
michael@0 | 15 | .set f15,15; .set f16,16; .set f17,17; .set f18,18; .set f19,19 |
michael@0 | 16 | .set f20,20; .set f21,21; .set f22,22; .set f23,23; .set f24,24 |
michael@0 | 17 | .set f25,25; .set f26,26; .set f27,27; .set f28,28; .set f29,29 |
michael@0 | 18 | .set f30,30; .set f31,31 |
michael@0 | 19 | |
michael@0 | 20 | # The ABI defines a fixed stack frame area of 4 doublewords (ELFv2) |
michael@0 | 21 | # or 6 doublewords (ELFv1); the last of these doublewords is used |
michael@0 | 22 | # as TOC pointer save area. The fixed area is followed by a parameter |
michael@0 | 23 | # save area of 8 doublewords (used for vararg routines), followed |
michael@0 | 24 | # by space for parameters passed on the stack. |
michael@0 | 25 | # |
michael@0 | 26 | # We set STACK_TOC to the offset of the TOC pointer save area, and |
michael@0 | 27 | # STACK_PARAMS to the offset of the first on-stack parameter. |
michael@0 | 28 | |
michael@0 | 29 | #if _CALL_ELF == 2 |
michael@0 | 30 | #define STACK_TOC 24 |
michael@0 | 31 | #define STACK_PARAMS 96 |
michael@0 | 32 | #else |
michael@0 | 33 | #define STACK_TOC 40 |
michael@0 | 34 | #define STACK_PARAMS 112 |
michael@0 | 35 | #endif |
michael@0 | 36 | |
michael@0 | 37 | # |
michael@0 | 38 | # NS_InvokeByIndex(nsISupports* that, uint32_t methodIndex, |
michael@0 | 39 | # uint32_t paramCount, nsXPTCVariant* params) |
michael@0 | 40 | # |
michael@0 | 41 | |
michael@0 | 42 | #if _CALL_ELF == 2 |
michael@0 | 43 | .section ".text" |
michael@0 | 44 | .type NS_InvokeByIndex,@function |
michael@0 | 45 | .globl NS_InvokeByIndex |
michael@0 | 46 | .align 2 |
michael@0 | 47 | NS_InvokeByIndex: |
michael@0 | 48 | 0: addis 2,12,(.TOC.-0b)@ha |
michael@0 | 49 | addi 2,2,(.TOC.-0b)@l |
michael@0 | 50 | .localentry NS_InvokeByIndex,.-NS_InvokeByIndex |
michael@0 | 51 | #else |
michael@0 | 52 | .section ".toc","aw" |
michael@0 | 53 | .section ".text" |
michael@0 | 54 | .align 2 |
michael@0 | 55 | .globl NS_InvokeByIndex |
michael@0 | 56 | .section ".opd","aw" |
michael@0 | 57 | .align 3 |
michael@0 | 58 | NS_InvokeByIndex: |
michael@0 | 59 | .quad .NS_InvokeByIndex,.TOC.@tocbase |
michael@0 | 60 | .previous |
michael@0 | 61 | .type NS_InvokeByIndex,@function |
michael@0 | 62 | .NS_InvokeByIndex: |
michael@0 | 63 | #endif |
michael@0 | 64 | mflr 0 |
michael@0 | 65 | std 0,16(r1) |
michael@0 | 66 | |
michael@0 | 67 | std r29,-24(r1) |
michael@0 | 68 | std r30,-16(r1) |
michael@0 | 69 | std r31,-8(r1) |
michael@0 | 70 | |
michael@0 | 71 | mr r29,r3 # Save 'that' in r29 |
michael@0 | 72 | mr r30,r4 # Save 'methodIndex' in r30 |
michael@0 | 73 | mr r31,r1 # Save old frame |
michael@0 | 74 | |
michael@0 | 75 | # Allocate stack frame with space for params. Since at least the |
michael@0 | 76 | # first 7 parameters (not including 'that') will be in registers, |
michael@0 | 77 | # we don't actually need stack space for those. We must ensure |
michael@0 | 78 | # that the stack remains 16-byte aligned. |
michael@0 | 79 | # |
michael@0 | 80 | # | (fixed area + | | 7 GP | 13 FP | 3 NV | |
michael@0 | 81 | # | param. save) |(params)........| regs | regs | regs | |
michael@0 | 82 | # (r1)......(+STACK_PARAMS)... (-23*8).(-16*8).(-3*8)..(r31) |
michael@0 | 83 | |
michael@0 | 84 | # +stack frame, -unused stack params, +regs storage, +1 for alignment |
michael@0 | 85 | addi r7,r5,((STACK_PARAMS/8)-7+7+13+3+1) |
michael@0 | 86 | rldicr r7,r7,3,59 # multiply by 8 and mask with ~15 |
michael@0 | 87 | neg r7,r7 |
michael@0 | 88 | stdux r1,r1,r7 |
michael@0 | 89 | |
michael@0 | 90 | |
michael@0 | 91 | # Call invoke_copy_to_stack(uint64_t* gpregs, double* fpregs, |
michael@0 | 92 | # uint32_t paramCount, nsXPTCVariant* s, |
michael@0 | 93 | # uint64_t* d)) |
michael@0 | 94 | |
michael@0 | 95 | # r5, r6 are passed through intact (paramCount, params) |
michael@0 | 96 | # r7 (d) has to be r1+STACK_PARAMS |
michael@0 | 97 | # -- where parameters are passed on the stack. |
michael@0 | 98 | # r3, r4 are above that, easier to address from r31 than from r1 |
michael@0 | 99 | |
michael@0 | 100 | subi r3,r31,(23*8) # r3 --> GPRS |
michael@0 | 101 | subi r4,r31,(16*8) # r4 --> FPRS |
michael@0 | 102 | addi r7,r1,STACK_PARAMS # r7 --> params |
michael@0 | 103 | bl invoke_copy_to_stack |
michael@0 | 104 | nop |
michael@0 | 105 | |
michael@0 | 106 | # Set up to invoke function |
michael@0 | 107 | |
michael@0 | 108 | ld r9,0(r29) # vtable (r29 is 'that') |
michael@0 | 109 | mr r3,r29 # self is first arg, obviously |
michael@0 | 110 | |
michael@0 | 111 | sldi r30,r30,3 # Find function descriptor |
michael@0 | 112 | add r9,r9,r30 |
michael@0 | 113 | ld r12,0(r9) |
michael@0 | 114 | |
michael@0 | 115 | std r2,STACK_TOC(r1) # Save r2 (TOC pointer) |
michael@0 | 116 | |
michael@0 | 117 | #if _CALL_ELF == 2 |
michael@0 | 118 | mtctr r12 |
michael@0 | 119 | #else |
michael@0 | 120 | ld r0,0(r12) # Actual address from fd. |
michael@0 | 121 | mtctr 0 |
michael@0 | 122 | ld r11,16(r12) # Environment pointer from fd. |
michael@0 | 123 | ld r2,8(r12) # TOC pointer from fd. |
michael@0 | 124 | #endif |
michael@0 | 125 | |
michael@0 | 126 | # Load FP and GP registers as required |
michael@0 | 127 | ld r4, -(23*8)(r31) |
michael@0 | 128 | ld r5, -(22*8)(r31) |
michael@0 | 129 | ld r6, -(21*8)(r31) |
michael@0 | 130 | ld r7, -(20*8)(r31) |
michael@0 | 131 | ld r8, -(19*8)(r31) |
michael@0 | 132 | ld r9, -(18*8)(r31) |
michael@0 | 133 | ld r10, -(17*8)(r31) |
michael@0 | 134 | |
michael@0 | 135 | lfd f1, -(16*8)(r31) |
michael@0 | 136 | lfd f2, -(15*8)(r31) |
michael@0 | 137 | lfd f3, -(14*8)(r31) |
michael@0 | 138 | lfd f4, -(13*8)(r31) |
michael@0 | 139 | lfd f5, -(12*8)(r31) |
michael@0 | 140 | lfd f6, -(11*8)(r31) |
michael@0 | 141 | lfd f7, -(10*8)(r31) |
michael@0 | 142 | lfd f8, -(9*8)(r31) |
michael@0 | 143 | lfd f9, -(8*8)(r31) |
michael@0 | 144 | lfd f10, -(7*8)(r31) |
michael@0 | 145 | lfd f11, -(6*8)(r31) |
michael@0 | 146 | lfd f12, -(5*8)(r31) |
michael@0 | 147 | lfd f13, -(4*8)(r31) |
michael@0 | 148 | |
michael@0 | 149 | bctrl # Do it |
michael@0 | 150 | |
michael@0 | 151 | ld r2,STACK_TOC(r1) # Load our own TOC pointer |
michael@0 | 152 | ld r1,0(r1) # Revert stack frame |
michael@0 | 153 | ld 0,16(r1) # Reload lr |
michael@0 | 154 | ld 29,-24(r1) # Restore NVGPRS |
michael@0 | 155 | ld 30,-16(r1) |
michael@0 | 156 | ld 31,-8(r1) |
michael@0 | 157 | mtlr 0 |
michael@0 | 158 | blr |
michael@0 | 159 | |
michael@0 | 160 | #if _CALL_ELF == 2 |
michael@0 | 161 | .size NS_InvokeByIndex,.-NS_InvokeByIndex |
michael@0 | 162 | #else |
michael@0 | 163 | .size NS_InvokeByIndex,.-.NS_InvokeByIndex |
michael@0 | 164 | #endif |
michael@0 | 165 | |
michael@0 | 166 | # Magic indicating no need for an executable stack |
michael@0 | 167 | .section .note.GNU-stack, "", @progbits ; .previous |