123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- /*++
- Copyright (c) 2015 Minoca Corp.
- This file is licensed under the terms of the GNU General Public License
- version 3. Alternative licensing terms are available. Contact
- info@minocacorp.com for details. See the LICENSE file at the root of this
- project for complete licensing information.
- Module Name:
- tlsaddr.S
- Abstract:
- This module implements functionality for fast access Thread Local Storage
- symbol lookup.
- Author:
- Evan Green 20-Apr-2015
- Environment:
- User Mode C Library
- --*/
- //
- // ------------------------------------------------------------------- Includes
- //
- #include <minoca/kernel/x86.inc>
- //
- // ---------------------------------------------------------------- Definitions
- //
- //
- // Define the offset of the TLS vector within the TCB.
- //
- .equ TCB_TLS_VECTOR_OFFSET, 0x4
- //
- // ----------------------------------------------------------------------- Code
- //
- //
- // .text specifies that this code belongs in the executable section.
- //
- // .code32 specifies that this is 32-bit protected mode code.
- //
- .text
- .code32
- //
- // LIBC_API
- // void *
- // ___tls_get_addr (
- // PTLS_INDEX Entry
- // )
- //
- /*++
- Routine Description:
- This routine returns the address of a thread-local symbol. References to
- this function are emitted directly by the compiler.
- Arguments:
- Entry - Supplies a pointer to the TLS symbol information. This argument is
- supplied in the eax register.
- Return Value:
- Returns a pointer to the thread local symbol.
- --*/
- EXPORTED_FUNCTION(___tls_get_addr)
- movl %gs:(TCB_TLS_VECTOR_OFFSET), %ecx # Get the TLS vector.
- movl (%eax), %edx # Get the module ID.
- cmpl %edx, (%ecx) # Compare module ID to generation number.
- jb ___tls_get_addrSlowPath
- movl (%ecx, %edx, 4), %ecx # Get the vector[ModuleId].
- cmpl $0, %ecx # Compare against NULL.
- je ___tls_get_addrSlowPath # Do the slow path if it's the first run.
- movl 4(%eax), %eax # Get the TLS entry offset.
- addl %ecx, %eax # Add in the TLS base.
- ret # Return the value.
- //
- // Call the slow C routine.
- //
- ___tls_get_addrSlowPath:
- pushl %ebx # Save ebx.
- call __x86.get_pc_thunk.bx # ebx must be set up correctly for the PLT.
- addl $_GLOBAL_OFFSET_TABLE_,%ebx # Get GOT address.
- pushl %eax # Push the structure parameter.
- call OsGetTlsAddress@PLT # Call the OS API routine.
- addl $4, %esp # Pop the parameter.
- popl %ebx # Restore ebx.
- ret # Return.
- END_FUNCTION(___tls_get_addr)
|