gcc '' आर्किटेक्चर '' शब्द का उपयोग विशिष्ट CPU के '' निर्देश सेट '' के लिए करता है, और "लक्ष्य" में CPU और आर्किटेक्चर के संयोजन को शामिल किया गया है, जैसे कि ABI, libc, एंडियन-नेस और अन्य जैसे अन्य चर (संभवतः "नंगे धातु" सहित)। एक विशिष्ट संकलक में लक्ष्य संयोजनों का एक सीमित सेट होता है (शायद एक एबीआई, एक सीपीयू परिवार, लेकिन संभवतः दोनों 32- और 64-बिट)। एक पार संकलक आमतौर पर साधन या तो सिस्टम के अलावा किसी अन्य लक्ष्य के साथ एक संकलक यह कई लक्ष्यों या कपड़े के साथ एक (यह भी देखें पर चलता है, या इस )।
क्या अलग-अलग सीपीयू आर्किटेक्चर में बायनेरी पोर्टेबल हैं?
सामान्य तौर पर, नहीं। पारंपरिक शब्दों में एक बाइनरी एक विशेष सीपीयू या सीपीयू परिवार के लिए मूल वस्तु कोड है। लेकिन, ऐसे कई मामले हैं जहां वे अत्यधिक पोर्टेबल के लिए मामूली हो सकते हैं:
- एक आर्किटेक्चर दूसरे का सुपरसेट है (आमतौर पर x86 बायनेरी लक्ष्य i386 या i686 के बजाय नवीनतम और सबसे बड़ा x86 का लक्ष्य है, उदाहरण के लिए
-march=core2
)
- एक आर्किटेक्चर मूल इम्यूलेशन या दूसरे का अनुवाद (आप क्रूसो के बारे में सुना हो सकता है ) प्रदान करता है, या संगत सह-प्रोसेसर प्रदान करता है (जैसे PS2 )
- OS और रनटाइम मल्टीकार का समर्थन करते हैं (उदाहरण के लिए x86_64 पर 32-बिट x 86 बायनेरिज़ चलाने की क्षमता), या VM / JIT को सहज बनाएं ( Dalvik या ART का उपयोग करके Android )
- "वसा" बायनेरिज़ के लिए समर्थन है जिसमें अनिवार्य रूप से प्रत्येक समर्थित वास्तुकला के लिए डुप्लिकेट कोड होते हैं
यदि आप किसी तरह इस समस्या को हल करने का प्रबंधन करते हैं, तो दूसरी पोर्टेबल बाइनरी समस्या है असंख्य पुस्तकालय संस्करणों की (glibc मैं आपको देख रहा हूं) आप स्वयं मौजूद होंगे। (अधिकांश एम्बेडेड सिस्टम आपको उस विशेष समस्या से कम से कम बचाते हैं।)
यदि आप पहले से नहीं हैं, तो अब दौड़ने gcc -dumpspecs
और gcc --target-help
यह देखने के लिए एक अच्छा समय है कि आप क्या कर रहे हैं।
फैट बायनेरिज़ में विभिन्न कमियां हैं , लेकिन अभी भी संभावित उपयोग ( ईएफआई ) हैं।
दो अन्य विचार हालांकि अन्य उत्तरों से गायब हैं: ELF और ELF दुभाषिया, और मनमाने ढंग से द्विआधारी प्रारूपों के लिए लिनक्स कर्नेल समर्थन । मैं यहाँ गैर-वास्तविक प्रोसेसर के लिए बायनेरिज़ या बायटेकोड के बारे में विस्तार से नहीं जाऊँगा, हालाँकि इनको "देशी" मानना और जावा या संकलित पायथन बायटेकोड बायनेरिज़ को निष्पादित करना संभव है , ऐसे बायनेरी हार्डवेयर आर्किटेक्चर से स्वतंत्र होते हैं (लेकिन निर्भर करते हैं प्रासंगिक वीएम संस्करण पर, जो अंततः एक देशी बाइनरी चलाता है)।
कोई भी समकालीन Linux सिस्टम ELF बायनेरिज़ ( इस PDF में तकनीकी विवरण ) का उपयोग करेगा , डायनेमिक ELF बायनेरिज़ के मामले में कर्नेल छवि में मेमोरी को लोड करने के लिए प्रभारी है, लेकिन यह ELF बायनेरिज़ का काम है। भारी उठाने के लिए शीर्षासन करें। आम तौर पर इसमें यह सुनिश्चित करना शामिल होता है कि सभी आश्रित डायनेमिक लाइब्रेरी उपलब्ध हैं ('' डायनामिक '' सेक्शन की मदद से जो लाइब्रेरियों और कुछ अन्य संरचनाओं को सूचीबद्ध करता है जो आवश्यक प्रतीकों को सूचीबद्ध करता है) - लेकिन यह लगभग एक सामान्य उद्देश्य अप्रत्यक्ष परत है।
$ file /bin/ls
/bin/ls: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses \
shared libs), stripped
$ readelf -p .interp /bin/ls
String dump of section '.interp':
[ 0] /lib/ld-linux.so.2
( /lib/ld-linux.so.2
एक ईएलएफ बाइनरी भी है, इसमें एक दुभाषिया नहीं है, और मूल बाइनरी कोड है।)
ईएलएफ के साथ समस्या यह है कि द्विआधारी में हेडर ( readelf -h /bin/ls
) एक विशिष्ट वास्तुकला, वर्ग (32- या 64-बिट), एंडियन-नेस और एबीआई (एप्पल के "सार्वभौमिक" वसा बायनेरिज़ के लिए एक वैकल्पिक द्विआधारी प्रारूप मच-ओ का उपयोग करता है) इसके बजाय जो इस समस्या को हल करता है, यह नेक्स्टस्टेप पर उत्पन्न हुआ है)। इसका मतलब यह है कि एक ईएलएफ निष्पादन योग्य को उस सिस्टम से मेल खाना चाहिए जिस पर इसे चलाया जाना है। एक एस्केप हैच दुभाषिया है, यह किसी भी निष्पादन योग्य हो सकता है (मूल रूप से द्विआधारी और उन्हें आमंत्रित करने वाले अर्क या नक्शे आर्किटेक्चर विशिष्ट सहित), लेकिन आप अभी भी ELF के प्रकार से विवश हैं, जो आपके सिस्टम को चलाने की अनुमति देगा। । (फ्रीबीएसडी के पास लिनक्स ईएलएफ फ़ाइलों को संभालने का एक दिलचस्प तरीका है , brandelf
यह ईएलएफ एबीआई क्षेत्र को संशोधित करता है।)
लिनक्स पर मच-ओ के लिए (उपयोग binfmt_misc
) समर्थन है , वहां एक उदाहरण है जो आपको दिखाता है कि वसा (32- और 64-बिट) द्विआधारी बनाने और चलाने के लिए कैसे। संसाधन कांटे / एडीएस , जैसा कि मूल रूप से मैक पर किया गया था, एक वर्कअराउंड हो सकता है, लेकिन कोई भी मूल लिनक्स फाइल सिस्टम इसका समर्थन नहीं करता है।
कमोबेश यही बात कर्नेल मॉड्यूल्स पर .ko
भी लागू होती है, फाइलें भी ELF हैं (हालांकि उनके पास कोई दुभाषिया सेट नहीं है)। इस मामले में एक अतिरिक्त परत है जो uname -r
खोज पथ में कर्नेल संस्करण ( ) का उपयोग करती है, कुछ ऐसा जो सैद्धांतिक रूप से ईएलएफ के बजाय संस्करणकरण के साथ किया जा सकता है, लेकिन कुछ जटिलता और थोड़े से लाभ पर मुझे संदेह है।
जैसा कि कहीं और उल्लेख किया गया है, लिनक्स मूल रूप से वसा बायनेरिज़ का समर्थन नहीं करता है, लेकिन एक सक्रिय वसा-बाइनरी प्रोजेक्ट है: फैटीएलएफ । यह लगभग वर्षों से है , इसे कभी-कभी पेटेंट चिंताओं के कारण मानक कर्नेल में आंशिक रूप से एकीकृत नहीं किया गया था। इस समय इसके लिए कर्नेल और टूलचिन समर्थन दोनों की आवश्यकता होती है। यह binfmt_misc
दृष्टिकोण का उपयोग नहीं करता है , यह साइड-ईएलएफ हेडर मुद्दों को चरणबद्ध करता है और वसा कर्नेल मॉड्यूल के लिए भी अनुमति देता है।
- अगर मेरे पास 'x86 टारगेट, लाइनक्स ओएस वर्जन xyz' पर चलने के लिए संकलित एक एप्लीकेशन है, तो क्या मैं उसी संकलित बाइनरी को किसी अन्य सिस्टम 'ARM टारगेट, linux OS वर्जन xyz' पर चला सकता हूं?
ईएलएफ के साथ नहीं, यह आपको ऐसा नहीं करने देगा।
- यदि ऊपर सच नहीं है, तो एकमात्र तरीका यह है कि प्रासंगिक टूलकिन 'उदाहरण के लिए, आर्म-लिनेक्स-गुनैबी' का उपयोग करके पुनर्निर्माण / पुनर्निर्माण के लिए एप्लिकेशन स्रोत कोड प्राप्त किया जाए?
सरल उत्तर है हां। (जटिल उत्तरों में एमुलेशन, इंटरमीडिएट रिप्रेजेंटेशन, ट्रांसलेटर और जेआईटी शामिल हैं। केवल एक i686 बाइनरी का उपयोग करने के लिए एक i686 बाइनरी को "डाउनग्रेड" करने के मामले के अलावा वे शायद यहां दिलचस्प नहीं हैं, और एबीआई फ़िक्सअप मूल कोड के अनुवाद के रूप में संभवतः कठिन हैं। )
- इसी तरह, अगर मेरे पास एक लोड करने योग्य कर्नेल मॉड्यूल (डिवाइस ड्राइवर) है जो 'x86 लक्ष्य, लिनक्स ओएस संस्करण xyz' पर काम करता है, तो क्या मैं उसी संकलन को उपयोग / लोड कर सकता हूं। किसी अन्य सिस्टम 'ARM लक्ष्य, linux OS संस्करण yyz' पर। ?
नहीं, ELF आपको ऐसा नहीं करने देगा।
- अगर ऊपर सच नहीं है, तो एकमात्र तरीका यह है कि संबंधित टूलकिन 'उदाहरण के लिए, आर्म-लिनेक्स-गुनैबी' का उपयोग करके पुनर्निर्माण / पुनर्निर्माण के लिए ड्राइवर स्रोत कोड प्राप्त किया जाए?
सरल उत्तर है हां। मेरा मानना है कि फेटेलएफ आपको .ko
मल्टी-आर्किटेक्चर बनाने की सुविधा देता है, लेकिन कुछ बिंदु पर प्रत्येक समर्थित आर्किटेक्चर के लिए एक बाइनरी संस्करण बनाना पड़ता है। जिन चीजों के लिए कर्नेल मॉड्यूल की आवश्यकता होती है वे अक्सर स्रोत के साथ आते हैं, और आवश्यकतानुसार बनाए जाते हैं, जैसे कि VirtualBox यह करता है।
यह पहले से ही एक लंबे समय तक चलने वाला उत्तर है, केवल एक और चक्कर है। कर्नेल में पहले से ही एक वर्चुअल मशीन है, जो एक समर्पित है: बीपीएफ वीएम जो पैकेट से मिलान करने के लिए उपयोग किया जाता है। मानव पठनीय फिल्टर "होस्ट फू और पोर्ट 22 नहीं") एक बायटेकोड पर संकलित है और कर्नेल पैकेट फ़िल्टर इसे निष्पादित करता है । नया ईएक्सपीएफ सिर्फ पैकेट के लिए नहीं है, सिद्धांत रूप में कि वीएम कोड किसी भी समकालीन लिनक्स में पोर्टेबल है, और llvm इसका समर्थन करता है, लेकिन सुरक्षा कारणों से यह शायद प्रशासनिक नियमों के अलावा किसी अन्य चीज के लिए उपयुक्त नहीं है।
अब, आप बाइनरी एक्ज़ीक्यूटेबल की परिभाषा के साथ कितने उदार हैं, इस पर निर्भर करता है कि आप binfmt_misc
शेल स्क्रिप्ट के साथ फैट बाइनरी सपोर्ट को लागू करने के लिए (एब) का उपयोग कर सकते हैं , और कंटेनर फॉर्म के रूप में जिप फाइलें:
#!/bin/bash
name=$1
prog=${1/*\//} # basename
prog=${prog/.woz/} # remove extension
root=/mnt/tmpfs
root=$(TMPDIR= mktemp -d -p ${root} woz.XXXXXX)
shift # drop argv[0], keep other args
arch=$(uname -m) # i686
uname_s=$(uname -s) # Linux
glibc=$(getconf GNU_LIBC_VERSION) # glibc 2.17
glibc=${glibc// /-} # s/ /-/g
# test that "foo.woz" can unzip, and test "foo" is executable
unzip -tqq "$1" && {
unzip -q -o -j -d ${root} "$1" "${arch}/${uname_s}/${glibc}/*"
test -x ${root}/$prog && (
export LD_LIBRARY_PATH="${root}:${LD_LIBRARY_PATH}"
#readlink -f "${root}/${prog}" # for the curious
exec -a "${name}" "${root}/${prog}" "$@"
)
rc=$?
#rm -rf -- "${root}/${prog}" # for the brave
exit $rc
}
इस "wozbin" को कॉल करें, और इसे कुछ इस तरह सेट करें:
mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
printf ":%s:%s:%s:%s:%s:%s:%s" \
"woz" "E" "" "woz" "" "/path/to/wozbin" "" > /proc/sys/fs/binfmt_misc/register
यह .woz
कर्नेल के साथ फाइल को पंजीकृत करता है, wozbin
स्क्रिप्ट को इसके बजाय पहले दर्ज किए गए तर्क के साथ लागू किया जाता .woz
है।
एक पोर्टेबल (वसा) .woz
फ़ाइल प्राप्त करने के लिए , बस test.woz
एक डायरेक्टरी पदानुक्रम के साथ एक ज़िप फ़ाइल बनाएँ :
i686/
\- Linux/
\- glibc-2.12/
armv6l/
\- Linux/
\- glibc-2.17/
प्रत्येक मेहराब / OS / libc निर्देशिका (एक मनमाना विकल्प) के भीतर आर्किटेक्चर-विशिष्ट test
बाइनरी और घटक जैसे कि .so
फाइलें रखें। जब आप इसे आमंत्रित करते हैं तो आवश्यक उपनिर्देशिका को एक tmpfs में मेमोरी फाइल सिस्टम ( /mnt/tmpfs
यहाँ पर ) में डाला जाता है और इनवोक किया जाता है।