2012-03-22 20 views
34

LD manual यह नहीं बताता कि KEEP कमांड क्या करता है। नीचे एक तृतीय-पक्ष लिंकर स्क्रिप्ट से एक स्निपेट है जिसमें KEEP है। KEEP कमांड ld में क्या करता है?एक लिंकर स्क्रिप्ट में क्या मतलब है?

SECTIONS 
{ 
    .text : 
    { 
     . = ALIGN(4); 
     _text = .; 
     PROVIDE(stext = .); 
     KEEP(*(.isr_vector)) 
     KEEP(*(.init)) 
     *(.text .text.*)   
     *(.rodata .rodata.*)   
     *(.gnu.linkonce.t.*) 
     *(.glue_7) 
     *(.glue_7t) 
     *(.gcc_except_table) 
     *(.gnu.linkonce.r.*) 
     . = ALIGN(4); 
     _etext = .; 
     _sidata = _etext; 
     PROVIDE(etext = .); 
      _fini = . ; 
       *(.fini) 

    } >flash 
+4

KEEP मैन्युअल के [इस] (https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep) संस्करण में प्रलेखित है। – alexei

उत्तर

37

अफैक एलडी खंडों में संदर्भ रखता है भले ही प्रतीकों का संदर्भ नहीं दिया गया हो। (--gc वर्गों)।

आमतौर पर उन वर्गों के लिए उपयोग किया जाता है जिनके पास बाइनरी स्टार्टअप प्रक्रिया में कुछ विशेष अर्थ होता है, निर्भरता पेड़ की जड़ों को चिह्नित करने के लिए अधिक या कम।


(नीचे Sabuncu के लिए)

निर्भरता पेड़:

आप अप्रयुक्त कोड को खत्म करने हैं, तो आप कोड का विश्लेषण और सभी पहुंच योग्य वर्गों (कोड + वैश्विक चर + स्थिरांक) निशान।

तो तुम एक अनुभाग चुनें "पुराना" के रूप में चिह्नित करें और देखें कि अन्य अनुभाग यह संदर्भ देता है, तो आप के रूप में "पुराना" उन खंड निशान, और जाँच वे क्या संदर्भ आदि

अनुभाग है कि नहीं कर रहे हैं चिह्नित "उपयोग" तो अनावश्यक हैं, और समाप्त किया जा सकता है।

चूंकि कोई अनुभाग कई अन्य वर्गों (उदाहरण के लिए तीन अलग-अलग अन्य लोगों को कॉल करने वाला एक प्रक्रिया) का संदर्भ दे सकता है, यदि आप परिणाम खींचेंगे तो आपको पेड़ मिल जाएगा।

रूट्स:

ऊपर सिद्धांत हालांकि एक समस्या के साथ हमें छोड़ देता है: "पहले" खंड है कि हमेशा इस्तेमाल किया क्या है? पेड़ के पहले नोड (रूट) तो बोलने के लिए? यह "रखता है()" करता है, यह लिंकर को बताता है कि कौन से अनुभाग (यदि उपलब्ध हैं) देखने वाले पहले व्यक्ति हैं। नतीजतन ये हमेशा जुड़े हुए हैं।

आम तौर पर ये वे अनुभाग हैं जिन्हें प्रोग्राम लोडर से डायनामिक लिंकिंग (वैकल्पिक, और ओएस/फ़ाइलफॉर्मेट आश्रित) से संबंधित कार्यों को करने के लिए कहा जाता है, और कार्यक्रम के प्रवेश बिंदु ।

+1

+1 निर्भरता पेड़ क्या है? इसकी जड़ों को चिह्नित करना क्यों महत्वपूर्ण है? धन्यवाद। – Sabuncu

+0

मैं पोस्ट के लिए एक संक्षिप्त स्पष्टीकरण जोड़ता हूं। –

+0

धन्यवाद! आप कहते हैं "... लिंकर को बताता है कि कौन से अनुभाग (यदि उपलब्ध हैं) पहले देखने वाले हैं।" यदि कोई भाग के रूप में चिह्नित किया गया है तो कोई अनुभाग क्यों उपलब्ध नहीं होगा? हो सकता है कि मैं यहां कुछ बुनियादी सिद्धांतों को याद कर रहा हूं, लेकिन यह विषय वास्तव में अस्पष्ट है (अभी तक महत्वपूर्ण है) और मुझे खुद को शिक्षित करने के लिए संसाधन ढूंढने में कठिनाई हो रही है। – Sabuncu

7

मिनिमल लिनक्स IA-32 उदाहरण है कि इसके उपयोग

main.S दिखाता है:

.section .text 
.global _start 
_start: 
    /* Dummy access so that after will be referenced and kept. */ 
    mov after, %eax 
    /*mov keep, %eax*/ 

    /* Exit system call. */ 
    mov $1, %eax 

    /* Take the exit status 4 bytes after before. */ 
    mov $4, %ebx 
    mov before(%ebx), %ebx 

    int $0x80 

.section .before 
    before: .long 0 
/* TODO why is the `"a"` required? */ 
.section .keep, "a" 
    keep: .long 1 
.section .after 
    after: .long 2 

लिंक।ld:

ENTRY(_start) 
SECTIONS 
{ 
    . = 0x400000; 
    .text : 
    { 
     *(.text) 
     *(.before) 
     KEEP(*(.keep)); 
     *(.keep) 
     *(.after) 
    } 
} 

संकलित करें और चलाने के:

as --32 -o main.o main.S 
ld --gc-sections -m elf_i386 -o main.out -T link.ld main.o 
./main.out 
echo $? 

आउटपुट:

1 

अगर हम बाहर टिप्पणी KEEP लाइन उत्पादन होता है:

2 

हम या तो हैं:

  • जोड़ने एक डमी mov keep, %eax
  • --gc-sections

उत्पादन 1 वापस चला जाता है हटा दें।

उबंटू 14.04, बिनुटिल्स 2.25 पर परीक्षण किया गया।

स्पष्टीकरण:

प्रतीक keep के लिए कोई संदर्भ नहीं है, और इसलिए अपनी अनुभाग .keep हैं।

इसलिए यदि कचरा संग्रह सक्षम है और हम अपवाद बनाने के लिए KEEP का उपयोग नहीं करते हैं, तो वह अनुभाग निष्पादन योग्य में नहीं रखा जाएगा।

हम before का पता करने के लिए 4 जोड़ रहे हैं, अगर keep अनुभाग मौजूद नहीं है, फिर बाहर निकलें स्थिति 2, जो अगले .after खंड पर मौजूद है हो जाएगा के बाद से।

TODO: .keep से "a" को हटाते हुए कुछ भी नहीं होता है, जो इसे आवंटित करता है। मुझे समझ में नहीं आता कि ऐसा क्यों है: वह अनुभाग .text सेगमेंट के अंदर रखा जाएगा, जिसके कारण इसका जादू नाम आवंटित होगा।

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

  • कोई संबंधित समस्या नहीं^_^