简体   繁体   English

设置自定义线程本地存储

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM