media/libvpx/vpx_ports/x86_abi_support.asm

Thu, 15 Jan 2015 15:59:08 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:59:08 +0100
branch
TOR_BUG_9701
changeset 10
ac0c01689b40
permissions
-rw-r--r--

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

mercurial