2011-07-07 10 views
23

x86-64 आर्किटेक्चर पर, दो रजिस्टरों का एक विशेष उद्देश्य है: एफएस और जीएस। लिनक्स 2.6। * में, एफएस रजिस्टर थ्रेड-स्थानीय जानकारी को स्टोर करने के लिए प्रयुक्त होता है।लिनक्स एएमडी 64 में एफएस/जीएस रजिस्टरों का उपयोग कैसे किया जाता है?

  • क्या यह सही है?
  • fs: 0 पर संग्रहीत क्या है? क्या कोई सी संरचना है जो इस सामग्री का वर्णन करती है?
  • तब जीएस का उपयोग क्या है?

उत्तर

28

x86-64 में 3 TLS entries कर रहे हैं, उनमें से दो FS and GS के माध्यम से उस तक पहुंच, एफएस आंतरिक glibc द्वारा (IA32 में जाहिरा तौर पर FS is used by Wine and GS by glibc) किया जाता है।

ग्लिबक अपने टीएलएस एंट्री पॉइंट को struct pthread पर बनाता है जिसमें थ्रेडिंग के लिए कुछ आंतरिक संरचनाएं होती हैं। ग्लिब आमतौर पर struct pthread वैरिएबल को pd के रूप में संदर्भित करता है, संभवतः pthread descriptor के लिए।

x86-64 पर, एक tcbhead_t साथ struct pthread शुरू होता है (इस आर्किटेक्चर पर निर्भर करता है, मैक्रोज़ TLS_DTV_AT_TP और TLS_TCB_AT_TP देखें)। इस थ्रेड कंट्रोल ब्लॉक हैडर, AFAIU में कुछ फ़ील्ड हैं जिन्हें एक थ्रेड होने पर भी आवश्यक है। डीटीवी गतिशील थ्रेड वेक्टर है, और इसमें dlopen() के माध्यम से लोड डीएसओ के लिए टीएलएस ब्लॉक के पॉइंटर्स शामिल हैं। टीसीबी से पहले या बाद में निष्पादन योग्य और डीएसओ (प्रोग्राम के) लोड समय से जुड़े एक स्थिर टीएलएस ब्लॉक है। टीसीबी और डीटीवी को Ulrich Drepper's TLS document में बहुत अच्छी तरह से समझाया गया है (अध्याय 3 में आरेखों की तलाश करें)।

+1

एफएस का उपयोग x86 पर x32 पर विंडोज थ्रेड जानकारी पर इंगित करने के लिए किया जाता है - शराब बस उससे मेल खाता है। –

10

वास्तव में अपने fs:0 प्रश्न का उत्तर देने के लिए: x86_64 एबीआई को fs:0 में fs द्वारा "इंगित किया गया" पता है। यही है, fs:-4fs:0 - 4 पर संग्रहीत मूल्य लोड करता है। यह सुविधा जरूरी है क्योंकि आप कर्नेल कोड के बिना fs द्वारा आसानी से पता लगा सकते हैं। fs:0 पर संग्रहीत पता होने के कारण इस प्रकार थ्रेड स्थानीय भंडारण के साथ काम करना अधिक कुशल होता है।

आप कार्रवाई में देख सकते हैं जब आप एक धागा स्थानीय चर का पता ले: एक ही लेकिन %gs के साथ करता है करने के लिए

f: 
    movq %fs:0, %rax 
    leaq -4(%rax), %rax 
    retq 

g: 
    movl %fs:-4, %eax 
    retq 

i686

static __thread int test = 0; 

int *f(void) { 
    return &test; 
} 

int g(void) { 
    return test; 
} 

संकलित करता है। Aarch64 पर यह आवश्यक नहीं है क्योंकि पते को टीएलएस रजिस्टर से ही पढ़ा जा सकता है।

संबंधित मुद्दे

 संबंधित मुद्दे