linker आउटपुट एलएफ फाइल के एक विशिष्ट भाग में एक अनुभाग/प्रतीक डालने के लिए GNU ld कैसे बताए/बल दें?



elf multiboot (1)

यह एक लंबा समय होगा, इसलिए कुछ कॉफी / चाय / यार्बा को पकड़ो।

सारांश

आउटपुट एलएफ फाइल के एक विशिष्ट भाग में एक अनुभाग / प्रतीक डालने के लिए GNU ld कैसे बताए / बल दें?

विशेष रूप से, मैं प्रतीक के भौतिक / लोड पते के बारे में नहीं पूछ रहा हूं, लेकिन फाइल के ऑफसेट के बारे में पूछता हूं।

पृष्ठभूमि

मैं एक असली दुनिया बीएसडी कर्नेल लेने की कोशिश कर रहा हूं और इसे GRUB के द्वारा Multiboot और बूट करने के साथ संगत कर रहा हूं। एक ELF छवि को multiboot के साथ संगत बनाने के लिए और GRUB द्वारा पहचाने जाने के लिए एक फ़ाइल की पहली 8KiB में जादू संख्या ( 0x1BADB002 ) को एम्बेड करने की आवश्यकता है।

मैं मल्टीबाट 0.6.96 का संदर्भ दे रहा हूँ।

जैसे मूल कर्नेल कोड का बहुत बड़ा टुकड़ा है, मैं ओएसडीव विकी से बियर बोनस कर्नेल के आधार पर उदाहरणों का उपयोग करने जा रहा हूं। जैसा कि कर्नेल पहले से ही Multiboot अनुरूप है, मैं अपने प्रश्न के उदाहरण के रूप में 0xCAFEBABE मान के साथ एक extra_symbol का उपयोग करने जा रहा हूं।

boot.s में शामिल हैं:

.set CAFEBABE, 0xCAFEBABE
; ... snip ...
.section .extras
extra_symbol:
    .long CAFEBABE

.text में अतिरिक्त प्रतीक

सबसे आसान विकल्प उस मान के साथ किसी अन्य चीज़ के पहले ही .text अनुभाग में एक प्रतीक डालना होगा:

.text BLOCK(4K) : ALIGN(4K)
{
    *(.extras)
    *(.multiboot)
    *(.text)
}

उदाहरण के लिए यह ठीक है, लेकिन असली बीएसडी कर्नेल के मामले में। टेक्स्ट फ़ाइल में 0x2000 (8KiB) के बाद शुरू होता है। यह दृष्टिकोण एक विकल्प नहीं है

अतिरिक्त अनुभाग .text से पहले?

एक और विकल्प पूरे डाल करने के लिए है। .extras अनुभाग से पहले। .extras मेरी भोलीपन में, मुझे आशा थी कि इससे पहले इस तरह के एक अनुभाग डालने से लिंकर स्क्रिप्ट में .text भी पहले से ही उत्पादन एल्फ में दिखाई देगा:

SECTIONS
{
    // ... some stuff ...

    .extras : { *(.extras) }

    .text BLOCK(4K) : ALIGN(4K)
    {
        *(.multiboot)
        *(.text)
    }

    // ... more stuff ...

}

ऐसा नहीं है, हालांकि:

$ i586-elf-readelf -S myos.bin 
There are 10 section headers, starting at offset 0x6078:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .extras           PROGBITS        00100000 006010 000004 00      0   0  1
  [ 2] .comment          PROGBITS        00000000 006014 000011 01  MS  0   0  1
  [ 3] .text             PROGBITS        00001000 001000 0001e4 00  AX  0   0 4096
  [ 4] .rodata.str1.1    PROGBITS        000011e4 0011e4 000016 01 AMS  0   0  1
  [ 5] .eh_frame         PROGBITS        000011fc 0011fc 000104 00   A  0   0  4
  [ 6] .bss              PROGBITS        00002000 002000 004010 00  WA  0   0 4096
  [ 7] .shstrtab         STRTAB          00000000 006025 000050 00      0   0  1
  [ 8] .symtab           SYMTAB          00000000 006208 000210 10      9  19  4
  [ 9] .strtab           STRTAB          00000000 006418 000130 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

वास्तव में, अनुभाग अनुभाग शीर्ष लेख तालिका में पहले आता है, लेकिन फ़ाइल में इसकी ऑफसेट ( 0x6010 )। 0x6010 बाद का तरीका है। वास्तव में, यह .bss बाद भी आता है।

प्रश्न

एएलएफ विनिर्देश स्पष्ट रूप से बताता है कि:

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

मैं इसका उपयोग कैसे कर सकता हूं और जीएनयू extra_symbol को फाइल में किसी भी अन्य अनुभाग से पहले मेरे extra_symbol (शायद पूरे .extras अनुभाग) को .extras , प्राथमिकता से ही एएलएफ हैडर के बाद?


अनुभाग को .text से पहले रखने के लिए, क्या आपने पहले ही ( A ) और निष्पादन योग्य ( X ) आवंटित करने का प्रयास किया है?

यदि .interp हैक काम करता है, तो ठीक है, बिल्कुल ठीक है।