memcpy

2011-06-20 12 views
9

पर कॉल डालने के बिना जीसीसी को संकलित करने के लिए प्राप्त करना मैं वर्तमान में पावरपीसी 440 के लिए संकलित जीसीसी 4.5.3 का उपयोग कर रहा हूं, और कुछ कोड संकलित कर रहा हूं जिनके लिए libc की आवश्यकता नहीं है। मेरे पास memcpy() के लिए कोई सीधी कॉल नहीं है, लेकिन संकलक निर्माण के दौरान एक डालने लगते हैं।memcpy

लिंकर विकल्प जैसे -nostdlib, -nostartfiles, -nodefaultlibs हैं लेकिन मैं उन्हें उपयोग करने में असमर्थ हूं क्योंकि मैं लिंकिंग चरण नहीं कर रहा हूं। मैं केवल संकलन कर रहा हूँ। कुछ इस तरह है:

$ powerpc-440-eabi-nm output.o | grep memcpy 
    U memcpy 
$ 

जीसीसी आदमी पेज यह स्पष्ट करता है memcpy के लिए कॉल को हटाने और करने के लिए कैसे:

$ powerpc-440-eabi-gcc -O2 -g -c -o output.o input.c 

अगर मैं एनएम के साथ output.o जाँच, मैं memcpy के लिए एक संदर्भ देखना लिंकर के साथ अन्य libc कॉल, लेकिन मैं नहीं चाहता कि संकलक उन्हें पहले स्थान पर डालें, क्योंकि मैं एक पूरी तरह से अलग लिंकर का उपयोग कर रहा हूं (जीएनयू के एलडी नहीं, और यह libc के बारे में नहीं जानता)।

आपकी सहायता के लिए धन्यवाद।

+0

कॉल करने से फायदा हो सकता है और कुछ नहीं काम करता है, एक सरल बाइट-दर-बाइट तो जोड़ सकते हैं, , कम से कम उपयोग किए जाने वाले मामलों के लिए कम से कम memcpy के सीपीयू-आधारित कार्यान्वयन संभवतः उत्तर पीओ से कम है यहाँ sted। –

उत्तर

5

आपको -फनो-बिल्टिन के साथ उस अनुकूलन को अक्षम करने की आवश्यकता है। सी पुस्तकालय के लिए memcpy संकलित करने की कोशिश करते समय मुझे यह समस्या थी। इसे खुद कहा जाता है। ऊप्स!

+1

आपके उत्तर के लिए धन्यवाद! मैनुअल के माध्यम से पढ़ने के बाद, ऐसा लगता है कि -फनो-बिल्टिन या -फ्रेस्टैंडिंग को वही करना चाहिए जो मुझे चाहिए। लेकिन उन कंपाइलर स्विच जोड़ने के बाद, मुझे अभी भी memcpy के दो संदर्भ मिल रहे हैं। कोई अन्य सुझाव? – Brian

+0

@ ब्रायन: मैंने एक ही समस्या को मारा है। क्या यह सिर्फ एक जीसीसी बग है? –

+0

हाँ, दुर्भाग्यवश, यह सही उत्तर नहीं है: ऐसे मामले हैं, जब 'mem * 'कॉल अभी भी डाली जाती हैं, इससे कोई फर्क नहीं पड़ता। Droopycom का जवाब देखें, यह असली है! –

3

तुम भी कर सकते हैं अपनी बाइनरी एक "फ्रीस्टैंडिंग" एक:

आईएसओ सी मानक परिभाषित करता है (खंड 4 में) कार्यान्वयन अनुरूप के दो वर्गों। एक अनुरूप मेजबान कार्यान्वयन पूरे मानक का समर्थन करता है [...]; एक अनुरूप फ्रीस्टैंडिंग कार्यान्वयन केवल कुछ लाइब्रेरी सुविधाओं को प्रदान करने के लिए आवश्यक है: उनमें,,, और; एएमडी 1 के बाद से, उन में भी; और सी 99 में, उन में भी और। [...]।

मानक भी सभी कार्यान्वयन के लिए कार्यक्रमों, एक फ्रीस्टैंडिंग पर्यावरण के लिए दो वातावरण परिभाषित करता है, जिसमें फ्रीस्टैंडिंग कार्यान्वयन की आवश्यकता से परे लाइब्रेरी सुविधाएं नहीं हो सकती हैं, जहां प्रोग्राम स्टार्टअप और समाप्ति का संचालन कार्यान्वयन-परिभाषित किया जाता है, और एक होस्टेड वातावरण, जिसकी आवश्यकता नहीं है, जिसमें सभी पुस्तकालय सुविधाएं प्रदान की जाती हैं और स्टार्टअप एक फ़ंक्शन int मुख्य (शून्य) या int मुख्य (int, char * []) ​​के माध्यम से होता है।

एक ओएस कर्नेल एक फ्रीस्टैंडिंग वातावरण होगा; एक ऑपरेटिंग सिस्टम की सुविधाओं का उपयोग कर एक कार्यक्रम आम तौर पर एक होस्टेड कार्यान्वयन में होगा।

(पैरा मेरे द्वारा जोड़ा)

अधिक here। और संबंधित जीसीसी विकल्प/एस (कीवर्ड -freestanding या -fno-builtin) here पाया जा सकता है।

5

जीसीसी कुछ परिस्थितियों में memcpy को कॉल करता है, उदाहरण के लिए यदि आप संरचना की प्रतिलिपि बना रहे हैं। जीसीसी व्यवहार को बदलने का कोई तरीका नहीं है लेकिन आप इस तरह की प्रतिलिपि से बचने के लिए अपने कोड को संशोधित करके इसे टालने का प्रयास कर सकते हैं। सबसे अच्छा शर्त यह समझने के लिए असेंबली को देखना है कि जीसीसी ने memcpy क्यों उत्सर्जित किया और इसके आसपास काम करने की कोशिश की। हालांकि यह परेशान होने जा रहा है, क्योंकि आपको मूल रूप से यह समझने की आवश्यकता है कि जीसीसी कैसे काम करता है। http://gcc.gnu.org/onlinedocs/gcc/Standards.html से

निकालें:

संकलक समर्थन जीसीसी द्वारा इस्तेमाल किया दिनचर्या में से अधिकांश libgcc में मौजूद हैं, लेकिन वहाँ कुछ अपवाद हैं। जीसीसी को फ्रीस्टैंडिंग पर्यावरण को memcpy, memmove, memset और memcmp प्रदान करने की आवश्यकता होती है।अंत में, यदि __builtin_trap का उपयोग किया जाता है, और लक्ष्य जाल पैटर्न को लागू नहीं करता है, तो जीसीसी निरस्त करने के लिए एक कॉल उत्सर्जित करेगा।

+0

हमने देखा कि जीसीसी ने memcpy का सहारा लिया जब हमने स्थानीय सरणी शुरू की: int x [4] = {1,2,3,4}; संभवतः जीसीसी को इस डेटा को स्थानीय स्टैक पर कॉपी करने के लिए प्रत्येक बार जब हम फ़ंक्शन में प्रवेश करते थे। तो इसे एक स्थिर परिभाषा में बदलकर समस्या दूर हो गई। स्थिर कॉन्स int x [4] = {1,2,3,4}; – phord

+1

हां, लेकिन आपने कोड का अर्थ भी बदल दिया: यानी यदि आपका फ़ंक्शन x बदल रहा है, तो यह अगले कॉल की शुरुआत में {1,2,3,4} नहीं होगा ... – Droopycom

+0

सही, लेकिन इस मामले में हम डेटा को बदलने का वादा नहीं करते हैं। हम इसे 'कॉन्स्ट int' सरणी के रूप में घोषित करके वादा सुनिश्चित करते हैं। और हाँ, हम खुद को दूर करने के द्वारा खुद को गोली मार सकते हैं, लेकिन हम यहां बंदूक सुरक्षा को बहुत गंभीरता से लेते हैं और इस तरह की मूर्खता का मनोरंजन नहीं करते हैं। शेष मुद्दा यह हो सकता है कि हमारी सरणी अब स्थानीय स्टैक के बजाय .data में है। लेकिन यह भी हमारे उपयोग के लिए चिंता का विषय नहीं है। YMMV। – phord

3

-fno-builtins या -ffreestanding करने की कोई जरूरत के रूप में वे अनावश्यक रूप से उपयोगी रखते हुए तो अवांछित व्यवहार को निष्क्रिय करने के लिए कई महत्वपूर्ण अनुकूलन

यह वास्तव में जीसीसी के पेड़ लूप-वितरित-पैटर्न द्वारा "अनुकूलित" है को निष्क्रिय कर देगा, नहीं है अंतर्निहित क्षमताओं, तुम बस का उपयोग कर सकते हैं:

-fno-tree-loop-distribute-patterns

Musl-libc इसके निर्माण के लिए इस ध्वज का उपयोग करता है और उनके कॉन्फ़िगर लिपि में निम्नलिखित टिप्पणी है (मैंने देखा स्रोत के माध्यम से और किसी मैक्रो नहीं मिला है, इसलिए इस पर्याप्त होना चाहिए) विकल्पों से
memcpy के आत्म-निर्देशात्मक संस्करणों पैदा # संकलक को रोकने के लिए आवश्यकता हो सकती है के लिए

# चेक ,, memmove, memcmp,
# और यादृच्छिक। वास्तव में, हम अगर यह
# विकल्प के लिए पर्याप्त है निर्धारित करने के लिए एक जांच जोड़ना चाहिए, और यदि नहीं, अस्थिर के साथ इन
# कार्यों को बिगाड़ रहा ... मैक्रो जोड़ने के
# tryflag CFLAGS_MEMOPS -fno पेड़ लूप-वितरित -patterns

इस जीसीसी में अलग-अलग कार्यों के लिए एक विशेषता के रूप में अपनी अनुकूलन विशेषता का उपयोग इतना है कि अन्य कार्यों mem*()

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