Thu, 15 Jan 2015 15:59:08 +0100
Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
michael@0 | 1 | ; |
michael@0 | 2 | ; Copyright (c) 2010 The WebM project authors. All Rights Reserved. |
michael@0 | 3 | ; |
michael@0 | 4 | ; Use of this source code is governed by a BSD-style license |
michael@0 | 5 | ; that can be found in the LICENSE file in the root of the source |
michael@0 | 6 | ; tree. An additional intellectual property rights grant can be found |
michael@0 | 7 | ; in the file PATENTS. All contributing project authors may |
michael@0 | 8 | ; be found in the AUTHORS file in the root of the source tree. |
michael@0 | 9 | ; |
michael@0 | 10 | |
michael@0 | 11 | |
michael@0 | 12 | %include "vpx_config.asm" |
michael@0 | 13 | |
michael@0 | 14 | ; 32/64 bit compatibility macros |
michael@0 | 15 | ; |
michael@0 | 16 | ; In general, we make the source use 64 bit syntax, then twiddle with it using |
michael@0 | 17 | ; the preprocessor to get the 32 bit syntax on 32 bit platforms. |
michael@0 | 18 | ; |
michael@0 | 19 | %ifidn __OUTPUT_FORMAT__,elf32 |
michael@0 | 20 | %define ABI_IS_32BIT 1 |
michael@0 | 21 | %elifidn __OUTPUT_FORMAT__,macho32 |
michael@0 | 22 | %define ABI_IS_32BIT 1 |
michael@0 | 23 | %elifidn __OUTPUT_FORMAT__,win32 |
michael@0 | 24 | %define ABI_IS_32BIT 1 |
michael@0 | 25 | %elifidn __OUTPUT_FORMAT__,aout |
michael@0 | 26 | %define ABI_IS_32BIT 1 |
michael@0 | 27 | %else |
michael@0 | 28 | %define ABI_IS_32BIT 0 |
michael@0 | 29 | %endif |
michael@0 | 30 | |
michael@0 | 31 | %if ABI_IS_32BIT |
michael@0 | 32 | %define rax eax |
michael@0 | 33 | %define rbx ebx |
michael@0 | 34 | %define rcx ecx |
michael@0 | 35 | %define rdx edx |
michael@0 | 36 | %define rsi esi |
michael@0 | 37 | %define rdi edi |
michael@0 | 38 | %define rsp esp |
michael@0 | 39 | %define rbp ebp |
michael@0 | 40 | %define movsxd mov |
michael@0 | 41 | %macro movq 2 |
michael@0 | 42 | %ifidn %1,eax |
michael@0 | 43 | movd %1,%2 |
michael@0 | 44 | %elifidn %2,eax |
michael@0 | 45 | movd %1,%2 |
michael@0 | 46 | %elifidn %1,ebx |
michael@0 | 47 | movd %1,%2 |
michael@0 | 48 | %elifidn %2,ebx |
michael@0 | 49 | movd %1,%2 |
michael@0 | 50 | %elifidn %1,ecx |
michael@0 | 51 | movd %1,%2 |
michael@0 | 52 | %elifidn %2,ecx |
michael@0 | 53 | movd %1,%2 |
michael@0 | 54 | %elifidn %1,edx |
michael@0 | 55 | movd %1,%2 |
michael@0 | 56 | %elifidn %2,edx |
michael@0 | 57 | movd %1,%2 |
michael@0 | 58 | %elifidn %1,esi |
michael@0 | 59 | movd %1,%2 |
michael@0 | 60 | %elifidn %2,esi |
michael@0 | 61 | movd %1,%2 |
michael@0 | 62 | %elifidn %1,edi |
michael@0 | 63 | movd %1,%2 |
michael@0 | 64 | %elifidn %2,edi |
michael@0 | 65 | movd %1,%2 |
michael@0 | 66 | %elifidn %1,esp |
michael@0 | 67 | movd %1,%2 |
michael@0 | 68 | %elifidn %2,esp |
michael@0 | 69 | movd %1,%2 |
michael@0 | 70 | %elifidn %1,ebp |
michael@0 | 71 | movd %1,%2 |
michael@0 | 72 | %elifidn %2,ebp |
michael@0 | 73 | movd %1,%2 |
michael@0 | 74 | %else |
michael@0 | 75 | movq %1,%2 |
michael@0 | 76 | %endif |
michael@0 | 77 | %endmacro |
michael@0 | 78 | %endif |
michael@0 | 79 | |
michael@0 | 80 | |
michael@0 | 81 | ; LIBVPX_YASM_WIN64 |
michael@0 | 82 | ; Set LIBVPX_YASM_WIN64 if output is Windows 64bit so the code will work if x64 |
michael@0 | 83 | ; or win64 is defined on the Yasm command line. |
michael@0 | 84 | %ifidn __OUTPUT_FORMAT__,win64 |
michael@0 | 85 | %define LIBVPX_YASM_WIN64 1 |
michael@0 | 86 | %elifidn __OUTPUT_FORMAT__,x64 |
michael@0 | 87 | %define LIBVPX_YASM_WIN64 1 |
michael@0 | 88 | %else |
michael@0 | 89 | %define LIBVPX_YASM_WIN64 0 |
michael@0 | 90 | %endif |
michael@0 | 91 | |
michael@0 | 92 | ; sym() |
michael@0 | 93 | ; Return the proper symbol name for the target ABI. |
michael@0 | 94 | ; |
michael@0 | 95 | ; Certain ABIs, notably MS COFF and Darwin MACH-O, require that symbols |
michael@0 | 96 | ; with C linkage be prefixed with an underscore. |
michael@0 | 97 | ; |
michael@0 | 98 | %ifidn __OUTPUT_FORMAT__,elf32 |
michael@0 | 99 | %define sym(x) x |
michael@0 | 100 | %elifidn __OUTPUT_FORMAT__,elf64 |
michael@0 | 101 | %define sym(x) x |
michael@0 | 102 | %elifidn __OUTPUT_FORMAT__,elfx32 |
michael@0 | 103 | %define sym(x) x |
michael@0 | 104 | %elif LIBVPX_YASM_WIN64 |
michael@0 | 105 | %define sym(x) x |
michael@0 | 106 | %else |
michael@0 | 107 | %define sym(x) _ %+ x |
michael@0 | 108 | %endif |
michael@0 | 109 | |
michael@0 | 110 | ; PRIVATE |
michael@0 | 111 | ; Macro for the attribute to hide a global symbol for the target ABI. |
michael@0 | 112 | ; This is only active if CHROMIUM is defined. |
michael@0 | 113 | ; |
michael@0 | 114 | ; Chromium doesn't like exported global symbols due to symbol clashing with |
michael@0 | 115 | ; plugins among other things. |
michael@0 | 116 | ; |
michael@0 | 117 | ; Requires Chromium's patched copy of yasm: |
michael@0 | 118 | ; http://src.chromium.org/viewvc/chrome?view=rev&revision=73761 |
michael@0 | 119 | ; http://www.tortall.net/projects/yasm/ticket/236 |
michael@0 | 120 | ; |
michael@0 | 121 | %ifdef CHROMIUM |
michael@0 | 122 | %ifidn __OUTPUT_FORMAT__,elf32 |
michael@0 | 123 | %define PRIVATE :hidden |
michael@0 | 124 | %elifidn __OUTPUT_FORMAT__,elf64 |
michael@0 | 125 | %define PRIVATE :hidden |
michael@0 | 126 | %elifidn __OUTPUT_FORMAT__,elfx32 |
michael@0 | 127 | %define PRIVATE :hidden |
michael@0 | 128 | %elif LIBVPX_YASM_WIN64 |
michael@0 | 129 | %define PRIVATE |
michael@0 | 130 | %else |
michael@0 | 131 | %define PRIVATE :private_extern |
michael@0 | 132 | %endif |
michael@0 | 133 | %else |
michael@0 | 134 | %define PRIVATE |
michael@0 | 135 | %endif |
michael@0 | 136 | |
michael@0 | 137 | ; arg() |
michael@0 | 138 | ; Return the address specification of the given argument |
michael@0 | 139 | ; |
michael@0 | 140 | %if ABI_IS_32BIT |
michael@0 | 141 | %define arg(x) [ebp+8+4*x] |
michael@0 | 142 | %else |
michael@0 | 143 | ; 64 bit ABI passes arguments in registers. This is a workaround to get up |
michael@0 | 144 | ; and running quickly. Relies on SHADOW_ARGS_TO_STACK |
michael@0 | 145 | %if LIBVPX_YASM_WIN64 |
michael@0 | 146 | %define arg(x) [rbp+16+8*x] |
michael@0 | 147 | %else |
michael@0 | 148 | %define arg(x) [rbp-8-8*x] |
michael@0 | 149 | %endif |
michael@0 | 150 | %endif |
michael@0 | 151 | |
michael@0 | 152 | ; REG_SZ_BYTES, REG_SZ_BITS |
michael@0 | 153 | ; Size of a register |
michael@0 | 154 | %if ABI_IS_32BIT |
michael@0 | 155 | %define REG_SZ_BYTES 4 |
michael@0 | 156 | %define REG_SZ_BITS 32 |
michael@0 | 157 | %else |
michael@0 | 158 | %define REG_SZ_BYTES 8 |
michael@0 | 159 | %define REG_SZ_BITS 64 |
michael@0 | 160 | %endif |
michael@0 | 161 | |
michael@0 | 162 | |
michael@0 | 163 | ; ALIGN_STACK <alignment> <register> |
michael@0 | 164 | ; This macro aligns the stack to the given alignment (in bytes). The stack |
michael@0 | 165 | ; is left such that the previous value of the stack pointer is the first |
michael@0 | 166 | ; argument on the stack (ie, the inverse of this macro is 'pop rsp.') |
michael@0 | 167 | ; This macro uses one temporary register, which is not preserved, and thus |
michael@0 | 168 | ; must be specified as an argument. |
michael@0 | 169 | %macro ALIGN_STACK 2 |
michael@0 | 170 | mov %2, rsp |
michael@0 | 171 | and rsp, -%1 |
michael@0 | 172 | lea rsp, [rsp - (%1 - REG_SZ_BYTES)] |
michael@0 | 173 | push %2 |
michael@0 | 174 | %endmacro |
michael@0 | 175 | |
michael@0 | 176 | |
michael@0 | 177 | ; |
michael@0 | 178 | ; The Microsoft assembler tries to impose a certain amount of type safety in |
michael@0 | 179 | ; its register usage. YASM doesn't recognize these directives, so we just |
michael@0 | 180 | ; %define them away to maintain as much compatibility as possible with the |
michael@0 | 181 | ; original inline assembler we're porting from. |
michael@0 | 182 | ; |
michael@0 | 183 | %idefine PTR |
michael@0 | 184 | %idefine XMMWORD |
michael@0 | 185 | %idefine MMWORD |
michael@0 | 186 | |
michael@0 | 187 | ; PIC macros |
michael@0 | 188 | ; |
michael@0 | 189 | %if ABI_IS_32BIT |
michael@0 | 190 | %if CONFIG_PIC=1 |
michael@0 | 191 | %ifidn __OUTPUT_FORMAT__,elf32 |
michael@0 | 192 | %define GET_GOT_SAVE_ARG 1 |
michael@0 | 193 | %define WRT_PLT wrt ..plt |
michael@0 | 194 | %macro GET_GOT 1 |
michael@0 | 195 | extern _GLOBAL_OFFSET_TABLE_ |
michael@0 | 196 | push %1 |
michael@0 | 197 | call %%get_got |
michael@0 | 198 | %%sub_offset: |
michael@0 | 199 | jmp %%exitGG |
michael@0 | 200 | %%get_got: |
michael@0 | 201 | mov %1, [esp] |
michael@0 | 202 | add %1, _GLOBAL_OFFSET_TABLE_ + $$ - %%sub_offset wrt ..gotpc |
michael@0 | 203 | ret |
michael@0 | 204 | %%exitGG: |
michael@0 | 205 | %undef GLOBAL |
michael@0 | 206 | %define GLOBAL(x) x + %1 wrt ..gotoff |
michael@0 | 207 | %undef RESTORE_GOT |
michael@0 | 208 | %define RESTORE_GOT pop %1 |
michael@0 | 209 | %endmacro |
michael@0 | 210 | %elifidn __OUTPUT_FORMAT__,macho32 |
michael@0 | 211 | %define GET_GOT_SAVE_ARG 1 |
michael@0 | 212 | %macro GET_GOT 1 |
michael@0 | 213 | push %1 |
michael@0 | 214 | call %%get_got |
michael@0 | 215 | %%get_got: |
michael@0 | 216 | pop %1 |
michael@0 | 217 | %undef GLOBAL |
michael@0 | 218 | %define GLOBAL(x) x + %1 - %%get_got |
michael@0 | 219 | %undef RESTORE_GOT |
michael@0 | 220 | %define RESTORE_GOT pop %1 |
michael@0 | 221 | %endmacro |
michael@0 | 222 | %endif |
michael@0 | 223 | %endif |
michael@0 | 224 | |
michael@0 | 225 | %ifdef CHROMIUM |
michael@0 | 226 | %ifidn __OUTPUT_FORMAT__,macho32 |
michael@0 | 227 | %define HIDDEN_DATA(x) x:private_extern |
michael@0 | 228 | %else |
michael@0 | 229 | %define HIDDEN_DATA(x) x |
michael@0 | 230 | %endif |
michael@0 | 231 | %else |
michael@0 | 232 | %define HIDDEN_DATA(x) x |
michael@0 | 233 | %endif |
michael@0 | 234 | %else |
michael@0 | 235 | %macro GET_GOT 1 |
michael@0 | 236 | %endmacro |
michael@0 | 237 | %define GLOBAL(x) rel x |
michael@0 | 238 | %ifidn __OUTPUT_FORMAT__,elf64 |
michael@0 | 239 | %define WRT_PLT wrt ..plt |
michael@0 | 240 | %define HIDDEN_DATA(x) x:data hidden |
michael@0 | 241 | %elifidn __OUTPUT_FORMAT__,elfx32 |
michael@0 | 242 | %define WRT_PLT wrt ..plt |
michael@0 | 243 | %define HIDDEN_DATA(x) x:data hidden |
michael@0 | 244 | %elifidn __OUTPUT_FORMAT__,macho64 |
michael@0 | 245 | %ifdef CHROMIUM |
michael@0 | 246 | %define HIDDEN_DATA(x) x:private_extern |
michael@0 | 247 | %else |
michael@0 | 248 | %define HIDDEN_DATA(x) x |
michael@0 | 249 | %endif |
michael@0 | 250 | %else |
michael@0 | 251 | %define HIDDEN_DATA(x) x |
michael@0 | 252 | %endif |
michael@0 | 253 | %endif |
michael@0 | 254 | %ifnmacro GET_GOT |
michael@0 | 255 | %macro GET_GOT 1 |
michael@0 | 256 | %endmacro |
michael@0 | 257 | %define GLOBAL(x) x |
michael@0 | 258 | %endif |
michael@0 | 259 | %ifndef RESTORE_GOT |
michael@0 | 260 | %define RESTORE_GOT |
michael@0 | 261 | %endif |
michael@0 | 262 | %ifndef WRT_PLT |
michael@0 | 263 | %define WRT_PLT |
michael@0 | 264 | %endif |
michael@0 | 265 | |
michael@0 | 266 | %if ABI_IS_32BIT |
michael@0 | 267 | %macro SHADOW_ARGS_TO_STACK 1 |
michael@0 | 268 | %endm |
michael@0 | 269 | %define UNSHADOW_ARGS |
michael@0 | 270 | %else |
michael@0 | 271 | %if LIBVPX_YASM_WIN64 |
michael@0 | 272 | %macro SHADOW_ARGS_TO_STACK 1 ; argc |
michael@0 | 273 | %if %1 > 0 |
michael@0 | 274 | mov arg(0),rcx |
michael@0 | 275 | %endif |
michael@0 | 276 | %if %1 > 1 |
michael@0 | 277 | mov arg(1),rdx |
michael@0 | 278 | %endif |
michael@0 | 279 | %if %1 > 2 |
michael@0 | 280 | mov arg(2),r8 |
michael@0 | 281 | %endif |
michael@0 | 282 | %if %1 > 3 |
michael@0 | 283 | mov arg(3),r9 |
michael@0 | 284 | %endif |
michael@0 | 285 | %endm |
michael@0 | 286 | %else |
michael@0 | 287 | %macro SHADOW_ARGS_TO_STACK 1 ; argc |
michael@0 | 288 | %if %1 > 0 |
michael@0 | 289 | push rdi |
michael@0 | 290 | %endif |
michael@0 | 291 | %if %1 > 1 |
michael@0 | 292 | push rsi |
michael@0 | 293 | %endif |
michael@0 | 294 | %if %1 > 2 |
michael@0 | 295 | push rdx |
michael@0 | 296 | %endif |
michael@0 | 297 | %if %1 > 3 |
michael@0 | 298 | push rcx |
michael@0 | 299 | %endif |
michael@0 | 300 | %if %1 > 4 |
michael@0 | 301 | push r8 |
michael@0 | 302 | %endif |
michael@0 | 303 | %if %1 > 5 |
michael@0 | 304 | push r9 |
michael@0 | 305 | %endif |
michael@0 | 306 | %if %1 > 6 |
michael@0 | 307 | %assign i %1-6 |
michael@0 | 308 | %assign off 16 |
michael@0 | 309 | %rep i |
michael@0 | 310 | mov rax,[rbp+off] |
michael@0 | 311 | push rax |
michael@0 | 312 | %assign off off+8 |
michael@0 | 313 | %endrep |
michael@0 | 314 | %endif |
michael@0 | 315 | %endm |
michael@0 | 316 | %endif |
michael@0 | 317 | %define UNSHADOW_ARGS mov rsp, rbp |
michael@0 | 318 | %endif |
michael@0 | 319 | |
michael@0 | 320 | ; Win64 ABI requires that XMM6:XMM15 are callee saved |
michael@0 | 321 | ; SAVE_XMM n, [u] |
michael@0 | 322 | ; store registers 6-n on the stack |
michael@0 | 323 | ; if u is specified, use unaligned movs. |
michael@0 | 324 | ; Win64 ABI requires 16 byte stack alignment, but then pushes an 8 byte return |
michael@0 | 325 | ; value. Typically we follow this up with 'push rbp' - re-aligning the stack - |
michael@0 | 326 | ; but in some cases this is not done and unaligned movs must be used. |
michael@0 | 327 | %if LIBVPX_YASM_WIN64 |
michael@0 | 328 | %macro SAVE_XMM 1-2 a |
michael@0 | 329 | %if %1 < 6 |
michael@0 | 330 | %error Only xmm registers 6-15 must be preserved |
michael@0 | 331 | %else |
michael@0 | 332 | %assign last_xmm %1 |
michael@0 | 333 | %define movxmm movdq %+ %2 |
michael@0 | 334 | %assign xmm_stack_space ((last_xmm - 5) * 16) |
michael@0 | 335 | sub rsp, xmm_stack_space |
michael@0 | 336 | %assign i 6 |
michael@0 | 337 | %rep (last_xmm - 5) |
michael@0 | 338 | movxmm [rsp + ((i - 6) * 16)], xmm %+ i |
michael@0 | 339 | %assign i i+1 |
michael@0 | 340 | %endrep |
michael@0 | 341 | %endif |
michael@0 | 342 | %endmacro |
michael@0 | 343 | %macro RESTORE_XMM 0 |
michael@0 | 344 | %ifndef last_xmm |
michael@0 | 345 | %error RESTORE_XMM must be paired with SAVE_XMM n |
michael@0 | 346 | %else |
michael@0 | 347 | %assign i last_xmm |
michael@0 | 348 | %rep (last_xmm - 5) |
michael@0 | 349 | movxmm xmm %+ i, [rsp +((i - 6) * 16)] |
michael@0 | 350 | %assign i i-1 |
michael@0 | 351 | %endrep |
michael@0 | 352 | add rsp, xmm_stack_space |
michael@0 | 353 | ; there are a couple functions which return from multiple places. |
michael@0 | 354 | ; otherwise, we could uncomment these: |
michael@0 | 355 | ; %undef last_xmm |
michael@0 | 356 | ; %undef xmm_stack_space |
michael@0 | 357 | ; %undef movxmm |
michael@0 | 358 | %endif |
michael@0 | 359 | %endmacro |
michael@0 | 360 | %else |
michael@0 | 361 | %macro SAVE_XMM 1-2 |
michael@0 | 362 | %endmacro |
michael@0 | 363 | %macro RESTORE_XMM 0 |
michael@0 | 364 | %endmacro |
michael@0 | 365 | %endif |
michael@0 | 366 | |
michael@0 | 367 | ; Name of the rodata section |
michael@0 | 368 | ; |
michael@0 | 369 | ; .rodata seems to be an elf-ism, as it doesn't work on OSX. |
michael@0 | 370 | ; |
michael@0 | 371 | %ifidn __OUTPUT_FORMAT__,macho64 |
michael@0 | 372 | %define SECTION_RODATA section .text |
michael@0 | 373 | %elifidn __OUTPUT_FORMAT__,macho32 |
michael@0 | 374 | %macro SECTION_RODATA 0 |
michael@0 | 375 | section .text |
michael@0 | 376 | %endmacro |
michael@0 | 377 | %elifidn __OUTPUT_FORMAT__,aout |
michael@0 | 378 | %define SECTION_RODATA section .data |
michael@0 | 379 | %else |
michael@0 | 380 | %define SECTION_RODATA section .rodata |
michael@0 | 381 | %endif |
michael@0 | 382 | |
michael@0 | 383 | |
michael@0 | 384 | ; Tell GNU ld that we don't require an executable stack. |
michael@0 | 385 | %ifidn __OUTPUT_FORMAT__,elf32 |
michael@0 | 386 | section .note.GNU-stack noalloc noexec nowrite progbits |
michael@0 | 387 | section .text |
michael@0 | 388 | %elifidn __OUTPUT_FORMAT__,elf64 |
michael@0 | 389 | section .note.GNU-stack noalloc noexec nowrite progbits |
michael@0 | 390 | section .text |
michael@0 | 391 | %elifidn __OUTPUT_FORMAT__,elfx32 |
michael@0 | 392 | section .note.GNU-stack noalloc noexec nowrite progbits |
michael@0 | 393 | section .text |
michael@0 | 394 | %endif |
michael@0 | 395 |