我正在实现一个非常小且静态链接程序的小型
我有两个字符串设置来尝试这个:
假设我将TCB放置在堆栈的某个位置:
然后将TLS区域放在其旁边,位置为
libc
子集,我认为添加TLS支持是一次很好的学习经验。我使用Ulrich Drepper的TLS文档作为参考。我有两个字符串设置来尝试这个:
static __thread const char msg1[] = "TLS (1).\n"; /* 10 bytes */
static __thread const char msg2[] = "TLS (2).\n"; /* 10 bytes */
编译器生成以下指令来访问它们:
mov rbx, QWORD PTR fs:0x0 ; Load TLS.
lea rsi, [rbx-0x14] ; Get a pointer to 'msg1'. 20 byte offset.
lea rsi, [rbx-0xa] ; Get a pointer to 'msg2'. 10 byte offset.
假设我将TCB放置在堆栈的某个位置:
struct tcb {
void* self; /* Points to self. I read that this was necessary somewhere. */
int errno; /* Per-thread errno variable. */
int padding;
};
然后将TLS区域放在其旁边,位置为
tls = &tcb - tls_size
。然后我设置FS寄存器指向fs = tls + tls_size
,并将TLS初始化图像复制到tls
中。但是,这样做不起作用。我已经验证了通过将tls_image
处的20个字节写入stdout
来正确定位TLS初始化图像。这要么让我相信我没有正确放置TCB和/或TLS区域,要么就是我没有遵守ABI。
- 我使用
arch_prctl(2)
设置FS寄存器。我需要以某种方式使用set_thread_area(2)
吗? - 我没有
dtv
。我假设这不是必需的,因为我是静态链接的。
有什么想法,我做错了什么吗?非常感谢!
libc.tls_size = 2*sizeof(void *)+size+align+sizeof(struct pthread);
和mem += sizeof(void *) * 2;
中的两个空指针是用来做什么的? - haste