tlsaddr.S 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. /*++
  2. Copyright (c) 2015 Minoca Corp.
  3. This file is licensed under the terms of the GNU General Public License
  4. version 3. Alternative licensing terms are available. Contact
  5. info@minocacorp.com for details. See the LICENSE file at the root of this
  6. project for complete licensing information.
  7. Module Name:
  8. tlsaddr.S
  9. Abstract:
  10. This module implements functionality for fast access Thread Local Storage
  11. symbol lookup.
  12. Author:
  13. Evan Green 21-Apr-2015
  14. Environment:
  15. User Mode C Library
  16. --*/
  17. //
  18. // ------------------------------------------------------------------- Includes
  19. //
  20. #include <minoca/kernel/arm.inc>
  21. //
  22. // ---------------------------------------------------------------- Definitions
  23. //
  24. //
  25. // Define the offset of the TLS vector within the TCB.
  26. //
  27. .equ TCB_TLS_VECTOR_OFFSET, 0x4
  28. //
  29. // ----------------------------------------------------------------------- Code
  30. //
  31. ASSEMBLY_FILE_HEADER
  32. //
  33. // LIBC_API
  34. // void *
  35. // __tls_get_addr (
  36. // PTLS_INDEX Entry
  37. // )
  38. //
  39. /*++
  40. Routine Description:
  41. This routine returns the address of a thread-local symbol. References to
  42. this function are emitted directly by the compiler.
  43. Arguments:
  44. Entry - Supplies a pointer to the TLS symbol information.
  45. Return Value:
  46. Returns a pointer to the thread local symbol.
  47. --*/
  48. EXPORTED_FUNCTION __tls_get_addr
  49. mrc p15, 0, %r2, c13, c0, 3 @ Get the TPIDRURO register.
  50. ldr %r2, [%r2, #TCB_TLS_VECTOR_OFFSET] @ Get the TLS vector.
  51. ldr %r3, [%r2] @ Get the generation number.
  52. ldr %r1, [%r0] @ Get the module ID.
  53. cmp %r1, %r3 @ Compare module ID to generation.
  54. bgt __tls_get_addrSlow @ Go to the slow path if too old.
  55. ldr %r2, [%r2, %r1, lsl #2] @ Get the TLS block for the module.
  56. cmp %r2, #0 @ Compare against zero.
  57. beq __tls_get_addrSlow @ Go to slow path if NULL.
  58. ldr %r0, [%r0, #4] @ Put the offset in R0.
  59. add %r0, %r0, %r2 @ Add the TLS block address.
  60. bx %lr @ Return.
  61. __tls_get_addrSlow:
  62. b OsGetTlsAddress @ Call the OS api.
  63. END_FUNCTION __tls_get_addr