Ubuntu 螺纹控制块(TLS变型2?)

Ubuntu 螺纹控制块(TLS变型2?),ubuntu,gcc,x86,elf,thread-local-storage,Ubuntu,Gcc,X86,Elf,Thread Local Storage,我目前正在实现一个模拟器来运行32位x86 ELF文件(用GCC编译),我正在尝试理解TLS(线程本地存储) 在阅读了乌尔里希·德雷珀关于这一主题的论文后,我有以下问题:- 据我所知,在%gs:0处引用的内存包含一个TCB(线程控制块)。但是,我找不到此地址存储的确切结构。通过搜索我的内核源代码,我可以找到两个看起来很有希望的结构(tcbhead_t和其他几个),但我知道在我的系统(Ubuntu 2.6.32-41-generic)上,存储在结构偏移量0x10处的值是指向uuu kernal_v

我目前正在实现一个模拟器来运行32位x86 ELF文件(用GCC编译),我正在尝试理解TLS(线程本地存储)

在阅读了乌尔里希·德雷珀关于这一主题的论文后,我有以下问题:-

据我所知,在%gs:0处引用的内存包含一个TCB(线程控制块)。但是,我找不到此地址存储的确切结构。通过搜索我的内核源代码,我可以找到两个看起来很有希望的结构(tcbhead_t和其他几个),但我知道在我的系统(Ubuntu 2.6.32-41-generic)上,存储在结构偏移量0x10处的值是指向uuu kernal_vsyscall函数的指针,这似乎与我看到的结构不匹配

如果有人能指出我遗漏了什么,建议一些相关文档,或者给我指出源代码的正确区域,我将不胜感激

谢谢


里克。

我不能为Linux说话,但一般来说,TLS存储用于允许每个线程分配特定于该线程的任意存储

我假设您实际上只是在模拟x86指令(在加载elf之后),所以elf在这里不感兴趣

在这种情况下,您需要模拟TLS存储。也就是说,对于每个(您必须跟踪此)仿真线程,您需要跟踪与该线程的GS寄存器关联的单独值。为此,您需要模拟OS线程创建/停止/检查/终止调用以及OS-TLS初始化调用。(仿真)线程创建调用将导致仿真VM内的特定分配空间分配给该仿真线程的GS寄存器


一旦你做到了这一点,模拟GS访问就足够了,因为关于TLS的其他一切都只是在进程空间中运行的常规机器指令。

我不能为Linux说话,但一般来说,TLS存储用于允许每个线程分配特定于该线程的任意存储

我假设您实际上只是在模拟x86指令(在加载elf之后),所以elf在这里不感兴趣

在这种情况下,您需要模拟TLS存储。也就是说,对于每个(您必须跟踪此)仿真线程,您需要跟踪与该线程的GS寄存器关联的单独值。为此,您需要模拟OS线程创建/停止/检查/终止调用以及OS-TLS初始化调用。(仿真)线程创建调用将导致仿真VM内的特定分配空间分配给该仿真线程的GS寄存器


一旦具备了这些功能,模拟GS访问就足够了,因为TLS的所有其他功能都只是在进程空间中运行的常规机器指令。

谢谢。我知道TLS存储每个线程的数据。当你说我需要回复OS TLS初始化时,我同意。我的问题是这是在哪里完成的/用什么结构完成的?ThanksIt在调用创建线程时完成;此时,操作系统在进程的虚拟空间的某个地方分配了一个TCB,并将GS寄存器设置为指向该线程所在的位置。当然,你必须模仿这一点。不知道Linux,但在Windows下有TLS分配/访问/更新例程,它们以线程可见/有趣的方式修改TCB的内容;你也必须模仿这些。但是你不应该做任何其他事情。。。。。。线程选择放在TLS插槽中的是它的业务,它将有机器代码(您已经在模拟)来处理该数据。因此,您不必关心引用的数据结构,就像emulator关心您正在仿真的机器代码访问的其他数据结构一样。。。。。。我能想到的唯一例外是,您认为有一些系统数据结构可以通过TCB访问(您提到了一些)。除非这些数据结构被记录为用户线程可访问(或者用户无论如何都可以访问它们),否则您不必模拟它们。如果它们被记录为用户线程可访问,那么您正在模拟的代码具有相应的访问它们的机器指令。在最坏的情况下,在创建线程时,您必须对它们进行设置,并用文档化的可访问值填充它们。如果真的有这样的事情,我会很惊讶。谢谢Ira,这确实澄清了一些查找相关代码的问题。正如您所说,机器代码确实有处理TLS数据的指令。但奇怪的是,我读过的文档说TCB的实现是给定内核的内部实现。但是,如果我用GCC编译一个C程序,libc启动代码(_libc_start_main)从envp获取AT_SYSINFO辅助向量,并将其存储在gs:0x10.0。我知道TLS存储每个线程的数据。当你说我需要回复OS TLS初始化时,我同意。我的问题是这是在哪里完成的/用什么结构完成的?ThanksIt在调用创建线程时完成;此时,操作系统在进程的虚拟空间的某个地方分配了一个TCB,并将GS寄存器设置为指向该线程所在的位置。当然,你必须模仿这一点。不知道Linux,但在Windows下有TLS分配/访问/更新例程,它们以线程可见/有趣的方式修改TCB的内容;你也必须模仿这些。但是你不应该做任何其他事情。。。。。。线程选择放在TLS插槽中的是它的业务,它将有机器代码(您已经在模拟)来处理该数据。因此,您不必关心引用的数据结构,就像emulator关心您正在仿真的机器代码访问的其他数据结构一样。。。。。。我能想到的唯一例外是,你相信有