2009-08-28 12 views
19

मैं लिनक्स के तहत एक साधारण उपयोगकर्ता-स्थान ईएलएफ लोडर लिख रहा हूं (क्यों? 'मज़ा' के लिए)। इस समय मेरा लोडर काफी सरल है और केवल स्थिर-लिंक वाली ईएलएफ फ़ाइलों को लोड करने के लिए डिज़ाइन किया गया है जिसमें स्थिति-स्वतंत्र कोड है।लोड-टाइम ईएलएफ स्थानांतरण

आम तौर पर, जब कोई प्रोग्राम कर्नेल के ईएलएफ लोडर द्वारा लोड किया जाता है, तो इसे अपने स्वयं के पता स्थान में लोड किया जाता है। इस प्रकार, डेटा सेगमेंट और कोड सेगमेंट को ईएलएफ सेगमेंट में निर्दिष्ट सही आभासी पते पर लोड किया जा सकता है।

मेरे मामले में, हालांकि, मैं कर्नेल से mmap के माध्यम से पते का अनुरोध कर रहा हूं, और ईएलएफ सेगमेंट में अनुरोध किए गए पते प्राप्त कर सकते हैं या नहीं। कोड कोड के लिए यह कोई समस्या नहीं है क्योंकि यह स्थिति स्वतंत्र है। हालांकि, यदि डेटा सेगमेंट अपेक्षित पते पर लोड नहीं होता है, तो कोड डेटा सेगमेंट में संग्रहीत कुछ भी सही ढंग से संदर्भित नहीं कर पाएगा।

दरअसल, मेरा लोडर एक साधारण असेंबली निष्पादन योग्य के साथ ठीक काम करता प्रतीत होता है जिसमें कोई डेटा नहीं होता है। लेकिन जैसे ही मैं डेटा सेगमेंट जोड़ता हूं और इसका संदर्भ देता हूं, निष्पादन योग्य सही ढंग से या SEGFAULT को चलाने में विफल रहता है।

कैसे, यदि संभव हो, तो क्या मैं सही स्थान पर इंगित करने के लिए डेटा सेगमेंट के किसी भी संदर्भ को ठीक कर सकता हूं? क्या इस उद्देश्य के लिए (स्थैतिक) ईएलएफ फ़ाइल में संग्रहीत एक स्थानांतरण अनुभाग है?

+1

क्या कारण है एमएपीएपी() प्रक्रिया के कारण अनुरोधित पते देकर विफल रहा है 'जो एमएमएपी को पहले से ही उस पते के स्थान में आवंटित किए गए पृष्ठों को कॉल कर रहा है? –

+0

हां, शायद यही कारण है। मैंने अपने कोड/डेटा को "रास्ते से बाहर" रखने के लिए 'ld' पूछने के बारे में सोचा था, लेकिन मैं सोच रहा था कि पहले एक सामान्य समाधान संभव था या नहीं। अगर मुझे यहां कोई प्रतिक्रिया नहीं मिलती है तो मैं आगे बढ़ सकता हूं और कोशिश कर सकता हूं। –

उत्तर

8

यदि आप .got अनुभाग, (वैश्विक ऑफ़सेट तालिका) में उपलब्ध पूर्ण पते को संशोधित करते हैं तो आपके प्रोग्राम को काम करना चाहिए। .text और .data के बीच नई दूरी को पूरा करने के लिए पूर्ण पता गणना को संशोधित करना सुनिश्चित करें, मुझे डर है कि आपको यह पता लगाने की आवश्यकता है कि यह जानकारी आपके आर्किटेक्चर के लिए कहां से आती है। Global Offset Table (Processor-Specific)

गुड लक:

इस देखें।

+0

के अधिकांश के लिए मानक उपकरण और प्रक्रियाओं का उपयोग कर सकते हैं, किसी को नई दूरी की गणना करने का प्रयास नहीं करना चाहिए। कुछ निर्देश सापेक्ष पते का उपयोग कर डेटा सेगमेंट की सामग्री का संदर्भ दे सकते हैं, और आगे बढ़ने वाले सेगमेंट को आसानी से तोड़ दिया जाएगा। सेगमेंट को सही तरीके से मैप करने के लिए, किसी को 'MAP_FIXED' का उपयोग करना चाहिए, इसलिए आवश्यक क्षेत्र उपलब्ध नहीं होने पर' mmap' कॉल विफल हो जाएगा, और/या दोनों सेगमेंट के लिए बड़े क्षेत्र को मानचित्र रूप से मानचित्रित करेगा, और फिर इसके हिस्सों को अनैप करें और स्थान पर अलग-अलग सेगमेंट मैप करें छेद का –

4

मुझे ऐसा कोई तरीका नहीं दिखता है जब तक कि आप कर्नेल द्वारा प्रदत्त वर्चुअल एड्रेस स्पेस को पूरी तरह से अनुकरण नहीं करते हैं, और उस वर्चुअल स्पेस के अंदर कोड चलाते हैं। जब आप फ़ाइल से डेटा अनुभाग को mmap करते हैं, तो आप आंतरिक रूप से इसे अपने ईएलएफ दुभाषिया के वर्चुअल एड्रेस स्पेस के अज्ञात पते पर स्थानांतरित कर रहे हैं, और आपका कोड किसी भी तरह से इसका संदर्भ नहीं दे पाएगा।

गलत साबित होने के लिए खुशी हुई। यहां सीखने के लिए कुछ बहुत अच्छा है।

+0

या विभिन्न प्रक्रियाओं में ईएलएफ और लोडर फ़ंक्शन को लक्षित किया गया है, जिसमें एक कम से कम भाग है जो एक अजीब पते पर लक्ष्य प्रक्रिया में होना चाहिए। इस तरह आप लोडर –

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