2016-06-19 13 views
9

ग्लोबल ऑफसेट टेबल (जीओटी): जीएलएफ ईएलएफ प्रतीकों (लागू जीसीसी) के स्थानांतरण के लिए उपयोग किया जाता है, यह प्रत्येक प्रक्रिया के लिए किसी विशिष्ट लिंकिंग के बिना समान बाइनरी साझा करने में मदद करता है। इस प्रकार स्मृति में एक ही बाइनरी छवि की प्रतियां कम कर देता है।जीसीसी

मेरा सवाल है, क्या R_386_GOT32, R_386_GOTOFF को स्थानांतरित करने का कोई तरीका है स्थानांतरित ईएलएफ छवि में स्थानांतरण स्थान प्रविष्टियां? मेरा मतलब है, क्या मैं जीसीसी को R_386_PC32 या R_386_32 जीओटी प्रकार स्थानांतरण के बजाय टाइप स्थानांतरित करने के लिए मजबूर कर सकता हूं?

यदि नहीं, तो आपके पास लागू करने के रास्ते समझा सकता है? मैं ईएलएफ के लिए गतिशील लिंकिंग और लोडिंग लाइब्रेरी लिख रहा हूं।

संपादित करें:
संदर्भ लिंक
https://docs.oracle.com/cd/E23824_01/html/819-0690/chapter6-74186.html
http://man7.org/linux/man-pages/man8/ld.so.8.html
http://wiki.osdev.org/ELF

+1

यह एक वैध सवाल है। हालांकि, यदि आप अपना खुद का गतिशील लिंकर लिख रहे हैं, तो आपको पूरे ईएलएफ विनिर्देश को बेहतर ढंग से पढ़ना चाहिए और उचित जीओटी स्थानांतरण लागू करना चाहिए। – 3442

+0

@ केमीलैंड मैं सहमत हूं, लेकिन अभी के लिए मैं समय की बाधा के कारण सीमित कार्यान्वयन करना चाहता हूं। – amaneureka

+0

नीट, यह वही है जो मुझे अपने खिलौने ओएस – minexew

उत्तर

7

अंत में मैं यह फटा!
नहीं है, यह संभव नहीं है गैर GOT प्रकार स्थानांतरण के साथ उत्पादन के लिए जीसीसी प्रतिबंधित करने के लिए है।
अब जीओटी प्रकार स्थानांतरण कैसे हल करें?
GOT तय 128KB स्मृति हिस्सा (यह लिखने पर प्रतिलिपि के सिद्धांत पर काम करता है) गतिशील लिंकर जो स्थानांतरण के लिए प्रविष्टियों शामिल द्वारा आवंटित की है।
गतिशील लिंकर केवल तब ही आवंटित करता है जब ईएलएफ बाइनरी में किसी भी प्रकार का (नीचे सूचीबद्ध) जीओटी स्थानांतरण हो।

R_386_GOTOFF(== 0x9)
यह स्थानांतरण प्रकार एक प्रतीक के मूल्य और वैश्विक ऑफसेट तालिका के पते के बीच अंतर की गणना करता है। यह वैश्विक ऑफसेट टेबल बनाने के लिए लिंक-एडिटर भी निर्देशित करता है।

R_386_GOTPC(== 0xA)
यह स्थान परिवर्तन प्रकार, जैसा दिखता है R_386_PC32 को छोड़कर वह अपने गणना में वैश्विक ऑफसेट तालिका के पते का उपयोग करता।

उन्हें कैसे लागू करने के लिए?
नोट: निम्न कोड-टुकड़ा Atom OS स्रोत कोड जो बंद स्रोत लाइसेंस द्वारा संरक्षित के अंतर्गत आता है। -fPIE या -fpie जो GOT अक्षम कर सकते हैं: लेकिन मैं (एटम डेवलपर) इसके द्वारा इस कोड का उपयोग :)

uint GOT = Heap.kmalloc(1024 * 128); // 128 KB 
    ... 
    private static void Relocate(Elf_Header* aHeader, Elf_Shdr* aShdr, uint GOT) 
    { 
     uint BaseAddress = (uint)aHeader; 
     Elf32_Rel* Reloc = (Elf32_Rel*)aShdr->sh_addr; 
     Elf_Shdr* TargetSection = (Elf_Shdr*)(BaseAddress + aHeader->e_shoff) + aShdr->sh_info; 

     uint RelocCount = aShdr->sh_size/aShdr->sh_entsize; 

     uint SymIdx, SymVal, RelocType; 
     for (int i = 0; i < RelocCount; i++, Reloc++) 
     { 
      SymVal = 0; 
      SymIdx = (Reloc->r_info >> 8); 
      RelocType = Reloc->r_info & 0xFF; 

      if (SymIdx != SHN_UNDEF) 
      { 
       if (RelocType == R_386_GOTPC) 
        SymVal = GOT; 
       else 
        SymVal = GetSymValue(aHeader, TargetSection->sh_link, SymIdx); 
      } 

      uint* add_ref = (uint*)(TargetSection->sh_addr + Reloc->r_offset); 
      switch(RelocType) 
      { 
       case R_386_32: 
        *add_ref = SymVal + *add_ref; // S + A 
        break; 
       case R_386_GOTOFF: 
        *add_ref = SymVal + *add_ref - GOT; // S + A - GOT 
        break; 
       case R_386_PLT32: // L + A - P 
       case R_386_PC32: // S + A - P 
       case R_386_GOTPC: // GOT + A - P 
        *add_ref = SymVal + *add_ref - (uint)add_ref; 
        break; 
       default: 
        throw new Exception("[ELF]: Unsupported Relocation type"); 
      } 
     } 
    } 
0

आप जीसीसी विकल्प का उपयोग करने की कोशिश कर सकते मुक्त घोषणा करते हैं।

+0

से ईएलएफ लोडिंग के लिए पूर्ण स्रोत कोड देख सकते हैं जो सभी प्रकार के स्थानांतरण को अक्षम कर देगा । और मैं स्थैतिक बाइनरी के साथ समाप्त हो जाऊंगा जो मैं स्मृति में किसी अन्य स्थान पर नहीं जा सकता। – amaneureka

+0

@amaneureka '-fPIE 'के पास स्थिर लिंकिंग के साथ कुछ लेना देना नहीं है। – yugr

+0

हाँ। मेरा मतलब है कि मैं गैर स्थानापन्न बाइनरी के साथ खत्म हो जाएगा। – amaneureka

1

जीसीसी -fno-plt -fno-पिक R_386_PC32 और R_386_32 (या कम से कम यह मेरे मामले में काम किया) के लिए स्थानांतरण प्रकार सीमित कर देगा। स्वीकार्य उत्तर दावा करने में भ्रामक है कि यह संभव नहीं है।