00001
00002 #include <stdio.h>
00003
00004 #include "converse.h"
00005 #include "cmitls.h"
00006
00007 #if CMK_HAS_ELF_H && CMK_HAS_TLS_VARIABLES
00008
00009 extern void* __executable_start;
00010
00011 static Addr getCodeSegAddr() {
00012 return (Addr) &__executable_start;
00013 }
00014
00015 static Ehdr* getELFHeader() {
00016 return (Ehdr*) getCodeSegAddr();
00017 }
00018
00019 static Phdr* getProgramHeader() {
00020 void* p = (void*) getELFHeader();
00021 p+=sizeof(Ehdr);
00022 return (Phdr*) p;
00023 }
00024
00025 Phdr* getTLSPhdrEntry() {
00026 int phnum, i;
00027 Ehdr* elfHeader;
00028 Phdr* progHeader;
00029
00030 elfHeader = getELFHeader();
00031 phnum = elfHeader->e_phnum;
00032 progHeader = getProgramHeader();
00033 for (i = 0; i < phnum; i++) {
00034 if (progHeader[i].p_type == PT_TLS) {
00035 return &progHeader[i];
00036 }
00037 }
00038 return NULL;
00039 }
00040
00041 void allocNewTLSSeg(tlsseg_t* t, CthThread th) {
00042 Phdr* phdr;
00043
00044 phdr = getTLSPhdrEntry();
00045 if (phdr != NULL) {
00046 t->size = phdr->p_memsz;
00047 t->align = phdr->p_align;
00048 t->memseg = (Addr)CmiIsomallocAlign(t->align, t->size, th);
00049 memset((void*)t->memseg, 0, t->size);
00050 memcpy((void*)t->memseg, (void*) (phdr->p_vaddr), (size_t)(phdr->p_filesz));
00051 t->memseg = (Addr)( ((void*)(t->memseg)) + t->size );
00052
00053 } else {
00054 t->memseg = (Addr)NULL;
00055 t->size = 0;
00056 t->align = 0;
00057 }
00058 }
00059
00060 void switchTLS(tlsseg_t* , tlsseg_t* ) __attribute__((optimize(0)));
00061
00062
00063
00064
00065
00066
00067 void switchTLS(tlsseg_t* cur, tlsseg_t* next) {
00068 #if CMK_TLS_SWITCHING64
00069 asm volatile ("movq %%fs:0x0, %0\n\t"
00070 "movq %1, %%fs:0x0\n\t"
00071 : "=r"(cur->memseg)
00072 : "r"(next->memseg));
00073 #elif CMK_TLS_SWITCHING32
00074 asm volatile ("movl %%gs:0x0, %0\n\t"
00075 "movl %1, %%gs:0x0\n\t"
00076 : "=r"(cur->memseg)
00077 : "r"(next->memseg));
00078 #else
00079 fprintf(stderr, "TLS globals are not supported.");
00080 abort();
00081 #endif
00082 }
00083
00084
00085 #endif