2010-08-26 7 views
13

एक प्रोग्राम के रूप में सी प्रोग्राम कैसे काम करते हैं और एक प्रोग्राम के लिए libc का उपयोग करने में सक्षम होने के लिए न्यूनतम स्तर की सामग्री मौजूद होनी चाहिए, मैंने मुख्य रूप से गैस और एलडी का उपयोग कर x86 असेंबली में प्रोग्राम करने का प्रयास करने के लिए इसे स्वयं लिया है। ।जीसीसी का उपयोग किये बिना एलडी के साथ सी मानक लाइब्रेरी का उपयोग करने वाले गैस असेंबली प्रोग्राम को कैसे लिंक करें?

एक मजेदार छोटी चुनौती के रूप में, मैंने सफलतापूर्वक इकट्ठा किया है और विभिन्न स्वयं निर्मित गतिशील पुस्तकालयों से जुड़े कई कार्यक्रमों को जोड़ा है, लेकिन मैं सीधे जीसीसी का उपयोग किए बिना libc फ़ंक्शन कॉल का उपयोग करने के लिए स्क्रैच से प्रोग्राम को कोड करने में सक्षम नहीं रहा ।

मैं व्यक्तिगत सी लाइब्रेरी फ़ंक्शंस के कॉलिंग सम्मेलनों को समझता हूं, और ओबीजेडम्प और रीडल्फ के उपयोग के माध्यम से जीसीसी से संकलित कार्यक्रमों का पूरी तरह से निरीक्षण किया गया है, लेकिन जहां तक ​​गैस असेंबली फ़ाइल में शामिल करने के लिए कहीं भी जानकारी प्राप्त नहीं हुई है, libc में सफलतापूर्वक लिंक करने के लिए ld में कौन से पैरामीटर का आह्वान करना है। किसी के पास इसका कोई अंतर्दृष्टि है?

मैं x86 मशीन पर लिनक्स चला रहा हूं।

उत्तर

17

कम से कम तीन चीजें हैं जिन्हें आपको टी करने की आवश्यकता है ओ सफलतापूर्वक गतिशील जोड़ने के साथ libc का उपयोग करें:

  1. लिंक /usr/lib/crt1.o, जो _start होता है, जो ELF द्विआधारी के लिए प्रवेश बिंदु हो जाएगा;
  2. लिंक /usr/lib/crti.o (libc से पहले) और /usr/lib/crtn.o (बाद), जो कुछ प्रारंभिकरण और अंतिमकरण कोड प्रदान करते हैं;
  3. लिंकर को बताएं कि द्विआधारी गतिशील लिंकर, /lib/ld-linux.so का उपयोग करेगा।

उदाहरण के लिए:

$ cat hello.s 
.text 
.globl main 
main: 
push %ebp 
mov %esp, %ebp 
pushl $hw_str 
call puts 
add $4, %esp 
xor %eax, %eax 
leave 
ret 

.data 
hw_str: 
.asciz "Hello world!" 

$ as -o hello.o hello.s 
$ ld -o hello -dynamic-linker /lib/ld-linux.so.2 /usr/lib/crt1.o /usr/lib/crti.o -lc hello.o /usr/lib/crtn.o 
$ ./hello 
Hello world! 
$ 
+0

बहुत उपयोगी है, जो बहुत सारी जानकारी को स्पष्ट करता है। मेरे कोड पर लागू करने पर, मुझे 2 त्रुटियां मिल रही हैं, "__libc_csu_fini '" और "अपरिभाषित संदर्भ" __libc_csu_init' " सभी ऑब्जेक्ट फ़ाइलों पर प्रतीक डंप करने के बाद, मैं उनको ढूंढने में विफल रहा प्रतीकों, और crt1.o प्रतीकों को बुलाता प्रतीत होता है। क्या ऐसी कोई चीज है जो संभवतः उन प्रतीकों को अपनी ऑब्जेक्ट फ़ाइल के अंदर रख सकती है? – Cyro

+0

वे सी पुस्तकालय के एक साझा हिस्से से आते हैं; '-lc' से लिंक करना'/usr/lib/libc.so' में खींचना चाहिए, जो वास्तव में एक लिंकर स्क्रिप्ट खंड है जो सही फ़ाइल ('/ usr/lib/libc_nonshared.a') का संदर्भ देता है। शायद लिंक आदेश के साथ एक समस्या है? मुझे पूरा यकीन है कि आप 'crt1.o' के बाद पहले 'crti.o'', फिर अपनी ऑब्जेक्ट्स और लाइब्रेरीज़, फिर अंत में 'crtn.o'' चाहते हैं - लेकिन हो सकता है कि आपकी ऑब्जेक्ट के बाद '-lc' आना चाहिए (बस 'crtn.o' से पहले), पहले नहीं। –

+0

मैं आगे बढ़ गया और /usr/lib/libc_nonshared.a के साथ बस -lc टाइप करने के बाद और पूरी चीज काम करने के बाद बस! बहुत - बहुत धन्यवाद! – Cyro

-1

मुझे लगता है कि कुछ इस तरह काम करना चाहिए:

  1. एक साधारण सी कार्यक्रम
  2. जीसीसी एस file.c
  3. संपादित file.s
  4. गैस file.s
  5. ld बनाने file.o -lc crt1.o -o myprog
2

आप विधानसभा में

मैथ्यू के जवाब main परिभाषित यदि आप न्यूनतम आवश्यकताओं को बताने का एक महान काम करता है।

मुझे आपको दिखाएं कि आपके सिस्टम में उन पथों को कैसे ढूंढें। रन:

gcc -v hello_world.c |& grep 'collect2' | tr ' ' '\n' 

और फिर मैथ्यू का उल्लेख किया गया फाइल उठाएं।

gcc -v आपको सटीक लिंकर कमांड जीसीसी उपयोग देता है।

collect2 आंतरिक निष्पादन योग्य जीसीसी एक लिंकर फ्रंट एंड के रूप में उपयोग करता है, जिसमें ld के समान इंटरफ़ेस है।

उबंटू में 14.04 64-बिट (जीसीसी 4।

ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 \ 
    /usr/lib/x86_64-linux-gnu/crt1.o \ 
    /usr/lib/x86_64-linux-gnu/crti.o \ 
    -lc hello_world.o \ 
    /usr/lib/x86_64-linux-gnu/crtn.o 

तुम भी -lgcc और -lgcc_s आवश्यकता हो सकती है: 8), मैं के साथ समाप्त हो गया। यह भी देखें: Do I really need libgcc?

आप विधानसभा

में _start निर्धारित करते हैं अगर मैं _start परिभाषित, glibc से हैलो दुनिया बस के साथ काम किया:

ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 -lc hello_world.o 

मुझे यकीन है कि अगर यह है नहीं कर रहा हूँ मजबूत, यानी crt प्रारंभिकताओं को ग्लिब फ़ंक्शन का आह्वान करने के लिए सुरक्षित रूप से छोड़ा जा सकता है। यह भी देखें: Why does an assembly program only work when linked with crt1.o crti.o and crtn.o?

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

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