Difference between revisions of "Thread Local Region"

From Nintendo Switch Brew
Jump to navigation Jump to search
m (Hexkyz moved page Thread Local Storage to Thread Local Region)
Line 1: Line 1:
This is the 0x200-byte TLS (thread local storage). It's base address is loaded via ARM threadid register tpidrro_el0. TLS for multiple threads are stored in the same page, with the first TLS normally located at page+0x200, because the first TLS spot is reserved for usermode exception handling.
+
This is the 0x200-byte thread local region. It's base address is loaded via ARM threadid register tpidrro_el0. TLR for multiple threads are stored in the same page, with the first TLR normally located at page+0x200, because the first TLR spot is reserved for usermode exception handling.
  
 
= Structure =
 
= Structure =
 +
This is "nn::svc::ThreadLocalRegion".
 +
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
 
! Offset
 
! Offset
 
! Size
 
! Size
 +
! Name
 
! Description
 
! Description
! Notes
 
 
|-
 
|-
 
| 0x0
 
| 0x0
 
| 0x100
 
| 0x100
 +
| MessageBuffer
 
| [[IPC_Marshalling|IPC]] command buffer.
 
| [[IPC_Marshalling|IPC]] command buffer.
|
 
 
|-
 
|-
 
| [8.0.0+] 0x100
 
| [8.0.0+] 0x100
 
| 0x2
 
| 0x2
| User Disable Count
+
| DisableCounter
 
| If userland sets this to non-zero, kernel will pin the thread and disallow calls to almost all SVCs.
 
| If userland sets this to non-zero, kernel will pin the thread and disallow calls to almost all SVCs.
 
|-
 
|-
 
| [8.0.0+] 0x102
 
| [8.0.0+] 0x102
 
| 0x2
 
| 0x2
| Interrupt Flag
+
| InterruptFlag
 
| If a context switch would have occurred when user disable count was non-zero, kernel will set this to 1. This signifies that the user must call [[SVC#SynchronizePreemptionState|SynchronizePreemptionState]] to unpin itself and regain access other SVCs.
 
| If a context switch would have occurred when user disable count was non-zero, kernel will set this to 1. This signifies that the user must call [[SVC#SynchronizePreemptionState|SynchronizePreemptionState]] to unpin itself and regain access other SVCs.
 
|-
 
|-
 
| 0x104
 
| 0x104
| 0xF4
+
| 0x4
| Unknown.
+
| Reserved
 +
|
 +
|-
 +
| 0x108
 +
| 0x78
 +
| Reserved
 +
|
 +
|-
 +
| 0x180
 +
| 0x50
 +
| Tls
 +
|
 +
|-
 +
| 0x1D0
 +
| 0x8
 +
| LocalePtr
 +
|
 +
|-
 +
| 0x1D8
 +
| 0x8
 +
| ErrnoVal
 +
|
 +
|-
 +
| 0x1E0
 +
| 0x8
 +
| ThreadData
 +
|
 +
|-
 +
| 0x1E8
 +
| 0x8
 +
| EhGlobals
 +
|
 +
|-
 +
| 0x1F0
 +
| 0x8
 +
| ThreadPointer
 
|
 
|
 
|-
 
|-
 
| 0x1F8
 
| 0x1F8
 
| 0x8
 
| 0x8
| Pointer to [[Thread_Local_Storage#Thread_context|thread context]].
+
| ThreadType
|
+
| Pointer to [[Thread_Local_Region#ThreadType|thread type]].
 
|}
 
|}
  
 
= Userland context =
 
= Userland context =
== Boot paramter ==
+
== OsBootParamter ==
 
This is "nn::os::detail::g_OsBootParamter".
 
This is "nn::os::detail::g_OsBootParamter".
  
Line 43: Line 80:
 
! Offset
 
! Offset
 
! Size
 
! Size
 +
! Name
 
! Description
 
! Description
 
|-
 
|-
 
| 0x00
 
| 0x00
 
| 0x04
 
| 0x04
 +
|
 
| Main thread handle.
 
| Main thread handle.
 
|-
 
|-
 
| 0x04
 
| 0x04
 
| 0x04
 
| 0x04
 +
|
 
| Always 0.
 
| Always 0.
 
|-
 
|-
 
| 0x08
 
| 0x08
 
| 0x30
 
| 0x30
 +
|
 
| Empty.
 
| Empty.
 
|}
 
|}
  
== Resource manager storage ==
+
== OsResourceManagerStorage ==
 
This is "nn::os::detail::g_OsResourceManagerStorage".
 
This is "nn::os::detail::g_OsResourceManagerStorage".
  
Line 65: Line 106:
 
! Offset
 
! Offset
 
! Size
 
! Size
 +
! Name
 
! Description
 
! Description
 
|-
 
|-
 
| 0x00
 
| 0x00
 
| 0x04
 
| 0x04
 +
|
 
| Always 0.
 
| Always 0.
 
|-
 
|-
 
| 0x04
 
| 0x04
 
| 0x10
 
| 0x10
 +
|
 
| Process PRNG.
 
| Process PRNG.
 
|-
 
|-
 
| 0x14
 
| 0x14
 
| 0x04
 
| 0x04
 +
|
 
| Padding.
 
| Padding.
 
|-
 
|-
 
| 0x18
 
| 0x18
 
| 0x08
 
| 0x08
 +
|
 
| Always set to 0.
 
| Always set to 0.
 
|-
 
|-
 
| 0x20
 
| 0x20
 
| 0x08
 
| 0x08
| [[SVC#svcGetInfo|AddressSpaceStart]] right shifted by 0x0C.
+
|
 +
| [[SVC#GetInfo|AddressSpaceStart]] right shifted by 0x0C.
 
|-
 
|-
 
| 0x28
 
| 0x28
 
| 0x08
 
| 0x08
| AddressSpaceEnd ([[SVC#svcGetInfo|AddressSpaceStart]] + [[SVC#svcGetInfo|AddressSpaceSize]]) right shifted by 0x0C and aligned to AddressSpaceAlign.
+
|
 +
| AddressSpaceEnd ([[SVC#GetInfo|AddressSpaceStart]] + [[SVC#GetInfo|AddressSpaceSize]]) right shifted by 0x0C and aligned to AddressSpaceAlign.
 
|-
 
|-
 
| 0x30
 
| 0x30
 
| 0x08
 
| 0x08
 +
|
 
| AddressSpaceAlign right shifted by 0x0C.
 
| AddressSpaceAlign right shifted by 0x0C.
 
|-
 
|-
 
| 0x38
 
| 0x38
 
| 0x08
 
| 0x08
 +
|
 
| Always 0.
 
| Always 0.
 
|-
 
|-
 
| 0x40
 
| 0x40
 
| 0x08
 
| 0x08
 +
|
 
| Always set to 0.
 
| Always set to 0.
 
|-
 
|-
 
| 0x48
 
| 0x48
 
| 0x08
 
| 0x08
| [[SVC#svcGetInfo|MapRegionBased]] right shifted by 0x0C.
+
|
 +
| [[SVC#GetInfo|MapRegionBased]] right shifted by 0x0C.
 
|-
 
|-
 
| 0x50
 
| 0x50
 
| 0x08
 
| 0x08
| MapRegionEnd ([[SVC#svcGetInfo|MapRegionBased]] + [[SVC#svcGetInfo|MapRegionSize]]) right shifted by 0x0C and aligned to MapRegionAlign.
+
|
 +
| MapRegionEnd ([[SVC#GetInfo|MapRegionBased]] + [[SVC#GetInfo|MapRegionSize]]) right shifted by 0x0C and aligned to MapRegionAlign.
 
|-
 
|-
 
| 0x58
 
| 0x58
 
| 0x08
 
| 0x08
 +
|
 
| MapRegionAlign right shifted by 0x0C.
 
| MapRegionAlign right shifted by 0x0C.
 
|-
 
|-
 
| 0x60
 
| 0x60
 
| 0x08
 
| 0x08
 +
|
 
| Always 0.
 
| Always 0.
 
|-
 
|-
 
| 0x68
 
| 0x68
 
| 0x08
 
| 0x08
 +
|
 
| Always 0.
 
| Always 0.
 
|-
 
|-
 
| 0x70
 
| 0x70
 
| 0x1D0
 
| 0x1D0
| Main [[Thread_Local_Storage#Thread_context|thread context]].
+
|
 +
| Main [[Thread_Local_Region#ThreadType|thread type]].
 
|-
 
|-
 
| 0x240
 
| 0x240
 
| 0x08
 
| 0x08
| Pointer to main [[Thread_Local_Storage#Thread_context|thread context]].
+
|
 +
| Pointer to main [[Thread_Local_Region#ThreadType|thread type]].
 
|-
 
|-
 
| 0x248
 
| 0x248
 
| 0x08
 
| 0x08
 +
|
 
| Unknown.
 
| Unknown.
 
|-
 
|-
 
| 0x250
 
| 0x250
 
| 0x08
 
| 0x08
 +
|
 
| Unknown.
 
| Unknown.
 
|-
 
|-
 
| 0x258
 
| 0x258
 
| 0x130
 
| 0x130
 +
|
 
| Always empty?
 
| Always empty?
 
|-
 
|-
 
| 0x388
 
| 0x388
 
| 0x08
 
| 0x08
| Pointer to [[Thread_Local_Storage#Resource_manager_storage|resource manager storage]] + 0x388.
+
|
 +
| Pointer to [[Thread_Local_Region#OsResourceManagerStorage|resource manager storage]] + 0x388.
 
|-
 
|-
 
| 0x390
 
| 0x390
 
| 0x08
 
| 0x08
| Pointer to [[Thread_Local_Storage#Resource_manager_storage|resource manager storage]] + 0x388.
+
|
 +
| Pointer to [[Thread_Local_Region#OsResourceManagerStorage|resource manager storage]] + 0x388.
 
|-
 
|-
 
| 0x398
 
| 0x398
 
| 0x08
 
| 0x08
 +
|
 
| Always 0.
 
| Always 0.
 
|-
 
|-
 
| 0x3A0
 
| 0x3A0
 
| 0x08
 
| 0x08
 +
|
 
| Always 0.
 
| Always 0.
 
|}
 
|}
  
== Thread context ==
+
== ThreadType ==
This structure is used for describing each thread's context. In the main thread's case, this structure comes from the [[Thread_Local_Storage#Resource_manager_storage|resource manager storage]].
+
This is "nn::os::ThreadType".
  
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 167: Line 232:
 
! Offset
 
! Offset
 
! Size
 
! Size
 +
! Name
 
! Description
 
! Description
 
|-
 
|-
 
| 0x00
 
| 0x00
| 0x08
+
| 0x10
| Pointer to [[Thread_Local_Storage#Thread_context|thread context]] + 0x1C8.
+
| AllThreadsListNode
|-
+
|  
| 0x08
 
| 0x08
 
| Pointer to [[Thread_Local_Storage#Thread_context|thread context]]
 
 
|-
 
|-
 
| 0x10
 
| 0x10
| 0x08
+
| 0x10
| Pointer to [[Thread_Local_Storage#Thread_context|thread context]] + 0x10.
+
| MultiWaitObjectList
|-
+
|  
| 0x18
 
| 0x08
 
| Pointer to [[Thread_Local_Storage#Thread_context|thread context]] + 0x10.
 
 
|-
 
|-
 
| 0x20
 
| 0x20
 
| 0x20
 
| 0x20
| Empty.
+
| Reserved
 +
|
 
|-
 
|-
 
| 0x40
 
| 0x40
| 0x04
+
| 0x01
 +
| State
 
| Thread status.
 
| Thread status.
 +
|-
 +
| 0x41
 +
| 0x01
 +
| StackIsAliased
 +
|
 +
|-
 +
| 0x42
 +
| 0x01
 +
| AutoRegistered
 +
|
 +
|-
 +
| 0x43
 +
| 0x01
 +
| SuspendCount
 +
|
 
|-
 
|-
 
| 0x44
 
| 0x44
| 0x04
+
| 0x02
 +
| BasePriority
 
| Thread priority minus 0x1C.
 
| Thread priority minus 0x1C.
 +
|-
 +
| 0x46
 +
| 0x02
 +
| Version
 +
|
 
|-
 
|-
 
| 0x48
 
| 0x48
 
| 0x08
 
| 0x08
 +
| OriginalStack
 
| Thread stack base address.
 
| Thread stack base address.
 
|-
 
|-
 
| 0x50
 
| 0x50
 
| 0x08
 
| 0x08
 +
| Stack
 
| Thread stack base address mirror.
 
| Thread stack base address mirror.
 
|-
 
|-
 
| 0x58
 
| 0x58
 
| 0x08
 
| 0x08
 +
| StackSize
 
| Thread stack size.
 
| Thread stack size.
 
|-
 
|-
 
| 0x60
 
| 0x60
 
| 0x08
 
| 0x08
| Thread stub pointer.
+
| Argument
 +
|
 
|-
 
|-
 
| 0x68
 
| 0x68
 
| 0x08
 
| 0x08
| Thread ID.
+
| ThreadFunction
 +
|
 
|-
 
|-
 
| 0x70
 
| 0x70
 
| 0x08
 
| 0x08
| Always 0?
+
| CurrentFiber
 +
|
 
|-
 
|-
 
| 0x78
 
| 0x78
 
| 0x08
 
| 0x08
| Always 0?
+
| InitialFiber
 +
|
 
|-
 
|-
 
| 0x80
 
| 0x80
| 0x08
 
| Always 0?
 
|-
 
| 0x88
 
 
| 0x100
 
| 0x100
 +
| TlsValueArray
 
| TLS slots.
 
| TLS slots.
 
|-
 
|-
| 0x188
+
| 0x180
 
| 0x20
 
| 0x20
 +
| ThreadNameBuffer
 
| Thread name.
 
| Thread name.
 
|-
 
|-
| 0x1A8
+
| 0x1A0
 
| 0x08
 
| 0x08
 +
| NamePointer
 
| Thread name address.
 
| Thread name address.
 
|-
 
|-
| 0x1B0
+
| 0x1A8
 
| 0x04
 
| 0x04
| Critical Section.
+
| CsThread
 +
| Critical Section Storage.
 
|-
 
|-
| 0x1B4
+
| 0x1AC
 
| 0x04
 
| 0x04
| Conditional Variable.
+
| CvThread
 +
| Conditional Variable Storage.
 
|-
 
|-
| 0x1B8
+
| 0x1B0
 
| 0x04
 
| 0x04
 +
| Handle
 
| Thread handle.
 
| Thread handle.
 
|-
 
|-
| 0x1BC
+
| 0x1B4
 
| 0x04
 
| 0x04
| Always 0.
+
| LockHistory
 +
|
 
|-
 
|-
| 0x1C0
+
| 0x1B8
 
| 0x08
 
| 0x08
| Thread global mutex.
+
| ThreadId
|-
+
|
| 0x1C8
 
| 0x08
 
| Unknown.
 
 
|}
 
|}

Revision as of 19:05, 3 September 2020

This is the 0x200-byte thread local region. It's base address is loaded via ARM threadid register tpidrro_el0. TLR for multiple threads are stored in the same page, with the first TLR normally located at page+0x200, because the first TLR spot is reserved for usermode exception handling.

Structure

This is "nn::svc::ThreadLocalRegion".

Offset Size Name Description
0x0 0x100 MessageBuffer IPC command buffer.
[8.0.0+] 0x100 0x2 DisableCounter If userland sets this to non-zero, kernel will pin the thread and disallow calls to almost all SVCs.
[8.0.0+] 0x102 0x2 InterruptFlag If a context switch would have occurred when user disable count was non-zero, kernel will set this to 1. This signifies that the user must call SynchronizePreemptionState to unpin itself and regain access other SVCs.
0x104 0x4 Reserved
0x108 0x78 Reserved
0x180 0x50 Tls
0x1D0 0x8 LocalePtr
0x1D8 0x8 ErrnoVal
0x1E0 0x8 ThreadData
0x1E8 0x8 EhGlobals
0x1F0 0x8 ThreadPointer
0x1F8 0x8 ThreadType Pointer to thread type.

Userland context

OsBootParamter

This is "nn::os::detail::g_OsBootParamter".

Offset Size Name Description
0x00 0x04 Main thread handle.
0x04 0x04 Always 0.
0x08 0x30 Empty.

OsResourceManagerStorage

This is "nn::os::detail::g_OsResourceManagerStorage".

Offset Size Name Description
0x00 0x04 Always 0.
0x04 0x10 Process PRNG.
0x14 0x04 Padding.
0x18 0x08 Always set to 0.
0x20 0x08 AddressSpaceStart right shifted by 0x0C.
0x28 0x08 AddressSpaceEnd (AddressSpaceStart + AddressSpaceSize) right shifted by 0x0C and aligned to AddressSpaceAlign.
0x30 0x08 AddressSpaceAlign right shifted by 0x0C.
0x38 0x08 Always 0.
0x40 0x08 Always set to 0.
0x48 0x08 MapRegionBased right shifted by 0x0C.
0x50 0x08 MapRegionEnd (MapRegionBased + MapRegionSize) right shifted by 0x0C and aligned to MapRegionAlign.
0x58 0x08 MapRegionAlign right shifted by 0x0C.
0x60 0x08 Always 0.
0x68 0x08 Always 0.
0x70 0x1D0 Main thread type.
0x240 0x08 Pointer to main thread type.
0x248 0x08 Unknown.
0x250 0x08 Unknown.
0x258 0x130 Always empty?
0x388 0x08 Pointer to resource manager storage + 0x388.
0x390 0x08 Pointer to resource manager storage + 0x388.
0x398 0x08 Always 0.
0x3A0 0x08 Always 0.

ThreadType

This is "nn::os::ThreadType".

Offset Size Name Description
0x00 0x10 AllThreadsListNode
0x10 0x10 MultiWaitObjectList
0x20 0x20 Reserved
0x40 0x01 State Thread status.
0x41 0x01 StackIsAliased
0x42 0x01 AutoRegistered
0x43 0x01 SuspendCount
0x44 0x02 BasePriority Thread priority minus 0x1C.
0x46 0x02 Version
0x48 0x08 OriginalStack Thread stack base address.
0x50 0x08 Stack Thread stack base address mirror.
0x58 0x08 StackSize Thread stack size.
0x60 0x08 Argument
0x68 0x08 ThreadFunction
0x70 0x08 CurrentFiber
0x78 0x08 InitialFiber
0x80 0x100 TlsValueArray TLS slots.
0x180 0x20 ThreadNameBuffer Thread name.
0x1A0 0x08 NamePointer Thread name address.
0x1A8 0x04 CsThread Critical Section Storage.
0x1AC 0x04 CvThread Conditional Variable Storage.
0x1B0 0x04 Handle Thread handle.
0x1B4 0x04 LockHistory
0x1B8 0x08 ThreadId