[英]Setup a custom Thread Local Storage
For some research related project of mine, I'm trying to setup a second TLS after a new thread is created.对于我的一些研究相关项目,我正在尝试在创建新线程后设置第二个 TLS。
I think I was able to find the code responsible of setting up the TLS in the pthread
library.我想我能够在pthread
库中找到负责设置 TLS 的代码。 For instance one function that interests me is: _dl_allocate_tls ()
from here .例如,我感兴趣的一个 function 是: _dl_allocate_tls ()
from here 。
So ideally I would like to write something along these lines:所以理想情况下,我想写一些类似的东西:
#include <elf/dl-tls.c>
#include <sys/syscall.h>
int main(int argc, char** argv) {
void* my_new_tls = _dl_allocate_tls();
syscall(SYS_arch_prctl, ARCH_SET_FS, my_new_tls);
}
Installing libc6-dev
on Ubuntu won't give me access to the above files/headers/code.在 Ubuntu 上安装libc6-dev
不会让我访问上述文件/标题/代码。 Any ideas on how could I call the above functions?关于如何调用上述函数的任何想法?
Also, any advice on how a custom TLS can be installed in less hacky, more proper way, is more than welcome!此外,任何关于如何以更简单、更正确的方式安装自定义 TLS 的建议都非常受欢迎!
If you want to use a second TLS space on x86-64, you need to use TLS with a %gs
segment base, not %fs
like the rest of the system.如果您想在 x86-64 上使用第二个 TLS 空间,您需要使用带有%gs
段基础的 TLS,而不是像系统的 rest 那样的%fs
。 If you do that, you can manage the thread-local memory just like any other memory, and you do not need to coordinate with glibc.如果这样做,您可以像管理任何其他 memory 一样管理线程本地 memory,并且您不需要与 glibc 协调。 It's what Wine does internally.这就是 Wine 在内部所做的。
I actually found that I could piggyback (or piggy-bug) on libc's loader to do the job for me.我实际上发现我可以在 libc 的加载器上搭载(或 piggy-bug)来为我完成这项工作。 Here is what I did for future reference:这是我为将来参考所做的:
// This is an amazing hack to directly call libc's loader in: glibc/elf/dl-tls.c
void *_dl_allocate_tls(void *mem);
// Include related structs from glibc/sysdeps/generic/dl-dtv.h and
// glibc/sysdeps/x86_64/nptl/tls.h
void *new_tls() {
tcbhead_t *n_tls = (tcbhead_t *)_dl_allocate_tls(NULL);
// For the following see: glibc/nptl/pthread_create.c
/* Reference to the TCB itself. */
// pd->header.self = pd;
n_tls->self = n_tls;
/* Self-reference for TLS. */
// pd->header.tcb = pd;
n_tls->tcb = n_tls;
/* Copy the stack guard canary. */
// THREAD_COPY_STACK_GUARD (pd);
n_tls->stack_guard = current_tls->stack_guard;
/* Copy the pointer guard value. */
// THREAD_COPY_POINTER_GUARD (pd);
n_tls->pointer_guard = current_tls->pointer_guard;
/* Setup tcbhead. */
// tls_setup_tcbhead (pd);
n_tls->feature_1 = current_tls->feature_1;
// End of: glibc/nptl/pthread_create.c
return n_tls;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.