Thread Local Region: Difference between revisions

Roblabla (talk | contribs)
m I can't math
No edit summary
 
(5 intermediate revisions by 4 users not shown)
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. Its 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. In threads created by sdk, tpidr_el0 is assigned to the ThreadPointer object from the thread local region.


= Structure =
= Structure =
This is "nn::svc::ThreadLocalRegion".
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
! Offset
! Offset
! Size
! Size
! Name
! Description
! Description
|-
|-
| 0x0
| 0x0
| 0x100
| 0x100
| MessageBuffer
| [[IPC_Marshalling|IPC]] command buffer.
| [[IPC_Marshalling|IPC]] command buffer.
|-
|-
| [8.0.0+] 0x100
| 0x100
| 0x4
| 0x2
| Preemption State
| [8.0.0+] DisableCounter
| If userland sets this to non-zero, kernel will pin the thread and disallow calls to almost all SVCs.
|-
| 0x102
| 0x2
| [8.0.0+] 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.
|-
|-
| 0x104
| 0x104
| 0xF4
| 0x1
| Unknown.
| [14.0.0+] CacheMaintenanceFlag
|
|-
| 0x105
| 0x7B
| 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 [[#ThreadType|thread type]].
|}
|}


= Userland context =
= Userland context =
== Boot paramter ==
== OsResourceManager ==
This is "nn::os::detail::g_OsBootParamter".
This is "nn::os::detail::OsResourceManager".


{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 33: Line 80:
! Offset
! Offset
! Size
! Size
! Name
! Description
! Description
|-
|-
| 0x00
| 0x0
| 0x04
| 0x14
| Main thread handle.
| [[#RngManager|RngManager]]
|
|-
| 0x14
| 0x4
| Reserved
|
|-
| 0x18
| 0x28
| [[#AslrSpaceManager|AslrSpaceManager]]
|
|-
| 0x40
| 0x28
| [[#StackGuardManager|StackGuardManager]]
|
|-
| 0x68
| 0x1F0
| [[#ThreadManager|ThreadManager]]
|
|-
| 0x258
| 0x110
| [[#TlsManager|TlsManager]]
|
|-
| 0x368
| 0x1
| [[#TickManager|TickManager]]
|  
|-
|-
| 0x04
| 0x369
| 0x04
| 0x7
| Always 0.
| Reserved
|  
|-
|-
| 0x08
| 0x370
| 0x30
| 0x30
| Empty.
| [[#MemoryHeapManager|MemoryHeapManager]]
|
|-
| 0x3A0
| 0x48
| [[#VammManager|VammManager]]
|
|}
|}


== Resource manager storage ==
=== RngManager ===
This is "nn::os::detail::g_OsResourceManagerStorage".
This is "nn::os::detail::RngManager".


{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 55: Line 141:
! Offset
! Offset
! Size
! Size
! Name
! Description
! Description
|-
|-
| 0x00
| 0x0
| 0x04
| 0x4
| Always 0.
| CriticalSection
|  
|-
|-
| 0x04
| 0x4
| 0x10
| 0x10
| Process PRNG.
| Random
|
|}
 
=== AslrSpaceManager ===
This is "nn::os::detail::AslrSpaceManager".
 
{| class="wikitable" border="1"
|-
|-
| 0x14
! Offset
| 0x04
! Size
| Padding.
! Name
! Description
|-
|-
| 0x18
| 0x0
| 0x08
| 0x20
| Always set to 0.
| [[#AddressSpaceAllocator|Allocator]]
|  
|-
|-
| 0x20
| 0x20
| 0x08
| 0x1
| [[SVC#svcGetInfo|AddressSpaceStart]] right shifted by 0x0C.
| Impl
|
|-
| 0x21
| 0x7
| Reserved
|
|}
 
=== StackGuardManager ===
This is "nn::os::detail::StackGuardManager".
 
{| class="wikitable" border="1"
|-
! Offset
! Size
! Name
! Description
|-
|-
| 0x28
| 0x0
| 0x08
| 0x20
| AddressSpaceEnd ([[SVC#svcGetInfo|AddressSpaceStart]] + [[SVC#svcGetInfo|AddressSpaceSize]]) right shifted by 0x0C and aligned to AddressSpaceAlign.
| [[#AddressSpaceAllocator|Allocator]]
|  
|-
|-
| 0x30
| 0x20
| 0x08
| 0x1
| AddressSpaceAlign right shifted by 0x0C.
| Impl
|  
|-
|-
| 0x38
| 0x21
| 0x08
| 0x7
| Always 0.
| Reserved
|
|}
 
=== ThreadManager ===
This is "nn::os::detail::ThreadManager".
 
{| class="wikitable" border="1"
|-
|-
| 0x40
! Offset
| 0x08
! Size
| Always set to 0.
! Name
! Description
|-
|-
| 0x48
| 0x0
| 0x08
| 0x1
| [[SVC#svcGetInfo|MapRegionBased]] right shifted by 0x0C.
| Impl
|  
|-
|-
| 0x50
| 0x1
| 0x08
| 0x7
| MapRegionEnd ([[SVC#svcGetInfo|MapRegionBased]] + [[SVC#svcGetInfo|MapRegionSize]]) right shifted by 0x0C and aligned to MapRegionAlign.
| Reserved
|  
|-
|-
| 0x58
| 0x8
| 0x08
| 0x1C0
| MapRegionAlign right shifted by 0x0C.
| [[#ThreadType|MainThread]]
|  
|-
|-
| 0x60
| 0x1C8
| 0x08
| 0x4
| Always 0.
| CriticalSection
|  
|-
|-
| 0x68
| 0x1CC
| 0x08
| 0x4
| Always 0.
| Reserved
|  
|-
|-
| 0x70
| 0x1D0
| 0x1D0
| Main [[Thread_Local_Storage#Thread_context|thread context]].
| 0x10
| AllThreadsList
|
|-
| 0x1E0
| 0x8
| TotalThreadStackSize
|
|-
| 0x1E8
| 0x4
| NumCreatedThreads
|
|-
| 0x1EC
| 0x4
| Reserved
|
|}
 
=== TlsManager ===
This is "nn::os::detail::TlsManager".
 
{| class="wikitable" border="1"
|-
! Offset
! Size
! Name
! Description
|-
| 0x0
| 0x4
| NumUsedTlsSlots
|
|-
| 0x4
| 0x4
| Reserved
|
|-
| 0x8
| 0x100
| TlsDestructorArray
|
|-
| 0x108
| 0x4
| TlsCriticalSection
|
|-
| 0x10C
| 0x4
| Reserved
|
|}
 
=== TickManager ===
This is "nn::os::detail::TickManager".
 
{| class="wikitable" border="1"
|-
! Offset
! Size
! Name
! Description
|-
| 0x0
| 0x1
| Impl
|
|}
 
=== MemoryHeapManager ===
This is "nn::os::detail::MemoryHeapManager".
 
{| class="wikitable" border="1"
|-
! Offset
! Size
! Name
! Description
|-
| 0x0
| 0x8
| HeapAddress
|
|-
| 0x8
| 0x8
| HeapSize
|
|-
|-
| 0x240
| 0x10
| 0x08
| 0x8
| Pointer to main [[Thread_Local_Storage#Thread_context|thread context]].
| UsedHeapSize
|
|-
| 0x18
| 0x10
| FreeMemoryList
|  
|-
|-
| 0x248
| 0x28
| 0x08
| 0x4
| Unknown.
| CriticalSection
|  
|-
|-
| 0x250
| 0x2C
| 0x08
| 0x4
| Unknown.
| Impl
|
|}
 
=== VammManager ===
This is "nn::os::detail::VammManager".
 
{| class="wikitable" border="1"
|-
|-
| 0x258
! Offset
| 0x130
! Size
| Always empty?
! Name
! Description
|-
|-
| 0x388
| 0x0
| 0x08
| 0x8
| Pointer to [[Thread_Local_Storage#Resource_manager_storage|resource manager storage]] + 0x388.
| ReservedRegionAddress
|  
|-
|-
| 0x390
| 0x8
| 0x08
| 0x8
| Pointer to [[Thread_Local_Storage#Resource_manager_storage|resource manager storage]] + 0x388.
| ReservedRegionSize
|  
|-
|-
| 0x398
| 0x10
| 0x08
| 0x30
| Always 0.
| ReaderWriterLock
|  
|-
|-
| 0x3A0
| 0x40
| 0x08
| 0x8
| Always 0.
| RegionManager
|  
|}
|}


== Thread context ==
=== AddressSpaceAllocator ===
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::detail::AddressSpaceAllocator".


{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 157: Line 394:
! Offset
! Offset
! Size
! Size
! Name
! Description
! Description
|-
|-
| 0x00
| 0x0
| 0x08
| 0x4
| Pointer to [[Thread_Local_Storage#Thread_context|thread context]] + 0x1C8.
| CriticalSection
|
|-
| 0x4
| 0x4
| Reserved
|  
|-
|-
| 0x08
| 0x8
| 0x08
| 0x8
| Pointer to [[Thread_Local_Storage#Thread_context|thread context]]
| BeginPage
|  
|-
|-
| 0x10
| 0x10
| 0x08
| 0x8
| Pointer to [[Thread_Local_Storage#Thread_context|thread context]] + 0x10.
| EndPage
|  
|-
|-
| 0x18
| 0x18
| 0x08
| 0x8
| Pointer to [[Thread_Local_Storage#Thread_context|thread context]] + 0x10.
| GuardPageCount
|
|}
 
== ThreadType ==
This is "nn::os::ThreadType".
 
{| class="wikitable" border="1"
|-
! Offset
! Size
! Name
! Description
|-
| 0x00
| 0x10
| AllThreadsListNode
|
|-
| 0x10
| 0x10
| MultiWaitObjectList
|
|-
|-
| 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
| Initially empty (contains unknown pointers).
| TlsValueArray
| 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
| Thread global mutex.
|-
| 0x1C8
| 0x08
| 0x08
| Unknown.
| ThreadId
|
|}
|}