2011-02-25 15 views
9

मुझे पोर्ट स्रोत कोड को एआरएम मंच से ले जाना है जो लिनक्स चलाता है। दुर्भाग्य से मैंने असाइन किए गए मेमोरी एक्सेस समस्याओं में भाग लिया है। स्रोत पॉइंटर कास्ट करता है और भारी पहुंचता है।एआरएम अनलिखित मेमोरी एक्सेस वर्कअराउंड

कोड नीचे दिए गए कोड को वायरस की तरह कोडबेस पर फैला है। मैं समस्याग्रस्त स्थानों को इंगित कर सकता हूं धन्यवाद जीसीसी -Wcast-align कमांड लाइन विकल्प के लिए धन्यवाद, लेकिन एक हजार से अधिक उदाहरण हैं।

u = (IEC_BOOL); 
(((*(IEC_LINT*)pSP).H < b.H) 
    || (((*(IEC_LINT*)pSP).H == b.H) && ((*(IEC_LINT*)pSP).L < b.L))) ? 1 : 0); 
*(IEC_DWORD OS_SPTR *)pSP = 
    (IEC_DWORD)(*(IEC_DWORD OS_SPTR *)pSP >> u); 
*(IEC_DWORD OS_SPTR *)pSP = 
    (IEC_DWORD)(*(IEC_DWORD OS_SPTR *)pSP << -u); 
u = (IEC_BYTE)((*(IEC_DINT*)pSP != b) ? 1 : 0); 
*(IEC_DWORD*)pSP = (IEC_DWORD)(*(IEC_DWORD*)pSP & w); 
(*(IEC_ULINT*)pSP).H += u.H; 
(((*(IEC_ULINT OS_SPTR *)pSP).H == b.H) 
    && ((*(IEC_ULINT OS_SPTR *)pSP).L > b.L))) ? 1 : 0); 
u = (IEC_BYTE)((*(IEC_REAL*)pSP >= b) ? 1 : 0); 

echo 2 > /proc/cpu/alignment पर का उपयोग लिनक्स कर्नेल समस्याओं को ठीक लेकिन उस एप्लिकेशन का प्रदर्शन एक मुद्दा यह है कि किसी भी अधिक स्वीकार्य नहीं है करने के लिए अवक्रमित है बनाता है।

मैंने जीसीसी (v4.4.1) कंपाइलर के लिए __unaligned या __packed कीवर्ड जैसे कुछ के लिए नेट की खोज की लेकिन अभी तक खाली हो गया है।

मैंने सोचा कि बहुत से पॉबलेमेटिक कोड लाइनों को कम या ज्यादा जटिल रेगेक्सप/प्रतिस्थापित के साथ तय किया जा सकता है लेकिन अब, थोड़ी देर के लिए ऐसा करने के बाद, यह दृष्टिकोण भी कठिन काम करेगा।

क्या आपके पास कोई सुझाव है कि यह काम कैसे प्राप्त किया जाए? मुझे लगता है कि एक जीसीसी 4.5 कंपाइलर प्लगइन अधिक हो जाएगा लेकिन नियमित अभिव्यक्तियों से कुछ बेहतर है? आप किस अन्य सुझाव के साथ आ सकते हैं? जरूरी नहीं कि सभी समस्या उदाहरणों को ठीक किया जाना चाहिए क्योंकि मैं अभी भी कुछ दुर्लभ मामलों के लिए कर्नेल पर भरोसा कर सकता हूं।

+11

मैं मजाक करने के लिए प्रेरित हूं कि इसे TheDailyWTF.com पर ले जाया जाना चाहिए। – Crashworks

+2

आधुनिक भाषाविज्ञान के हमारे अध्ययन को जारी रखते हुए, यहां हमारे पास आमतौर पर एम्बेडेड प्रोग्रामर द्वारा उपयोग की जाने वाली सी की बोली का नमूना है। अंग्रेजी में शायद ही अनुवाद किया गया है, उपर्युक्त पाठ का अर्थ है "एफ *** आप!", हालांकि कोई भी प्राकृतिक भाषा वास्तव में पवित्रता की मात्रा, पवित्र के खिलाफ अवज्ञा, और पाठक की मानवता के लिए सामान्य उपेक्षा को व्यक्त नहीं कर सकती है। – Dmitri

उत्तर

7

__attribute__((__packed__)) है जो कुछ मामलों में मदद कर सकता है, लेकिन मुझे सच में लगता है कि इस कोड को बाद में जल्द से जल्द साफ किया जाना चाहिए, क्योंकि ऐसा लगता है कि आप समस्याओं को हल करने के लिए अधिक समय बिताएंगे और सभी के लिए।

+1

मुझे लगता है कि यह एक व्यवहार्य कामकाज है, लेकिन जो भी पहले कोड में कोड लिखा है उसे निकाल दिया जाना चाहिए। जिस तरह से कोड को इन सभी पॉइंटर्स पर '-फनो-सख्त-एलियासिंग' या '__attribute __ ((may_alias)) की आवश्यकता होती है, यदि यह टूटा हुआ है ... –

+0

यह IEC_DWORD * केस की मदद नहीं करेगा क्योंकि यह मूल रूप से एक है typedef uint32_t, पीओडी प्रकार। जिस क्षण एक पॉइंटर डाला जाता है, उसके पास 4 बाइट संरेखण होता है। जब कोड टूटा हुआ होता है, तो यह लक्ष्य के लिए एक एमुलेटर लिखने के लिए मोहक है :) –

+0

'__attribute __ ((__ पैक किया गया __)) पहले से ही संरचना सदस्यों के लिए उपयोग किया जा चुका है, लेकिन चूंकि संरचना संरचनाओं के बजाय पीओडी प्रकारों तक पहुंचती है यह बेकार है। लेकिन मैं यह देखने के लिए एक परीक्षण कार्यक्रम के साथ प्रयास करूंगा कि मैं इसका उपयोग कर सकता हूं या नहीं। – trenki

0

हम मान सकते हैं कि समस्या इस तथ्य से उत्पन्न होती है कि एआरएम 32 बिट मशीन है और लिनक्स बॉक्स 64 बिट मोड में चलता है, वैकल्पिक रूप से, कोड यह मान सकता है कि 16 बिट मशीन पर चल रहा है।

एक तरीका अंतर्निहित संरचना को देखने के लिए होगा। सदस्य "एच" और "एल" 32 बिट प्रकार हो सकते हैं जिन्हें एक्सेस किया जाता है जैसे कि वे 64 बिट हैं।

कोड को बेहतर व्यवहार करने के लिए एल और एच के प्रकारों को संशोधित करने का प्रयास करें।

(वैसे, इस हवा में एक चाकू, के रूप में कोड स्निपेट आवेदन का विवरण प्रकट नहीं करता है, अंतर्निहित संरचनाओं की है और न ही है।)

2

वाह, यह एक अपवित्र गड़बड़ है। कंपाइलर के साथ झुकाव आपको कहीं भी नहीं जा रहा है। कोड सभी आर्किटेक्चर पर अवैध है, लेकिन कुछ (जैसे x86) पर काम करना होता है। मैं कोड को ठीक कर दूंगा।

अफसोस की बात है कि ऐसा करने का कोई शानदार तरीका नहीं है। हालांकि, आपको खोज-और-प्रतिस्थापन की एक लंबी सूची के साथ लंबा रास्ता मिल सकता है, फिर मैन्युअल रूप से बाकी को ठीक कर दें। मैं उन डेटा प्रकारों की घोषणाओं को हटाकर शुरू करूंगा, इसलिए यदि आप किसी भी कोड को संकलित करते हैं, तो यह त्रुटि होगी। फिर, "* (IEC_DWORD OS_SPTR *) पीएसपी =" "set_dword (पीएसपी," के साथ स्निपेट को खोजें और प्रतिस्थापित करें। सही चीज़ करने के लिए एक इनलाइन फ़ंक्शन "set_dword" बनाएं। कई के लिए चलें आसानी से स्निपेट को प्रतिस्थापित कर सकते हैं जैसा कि आप कल्पना कर सकते हैं। अभी भी हाथ से ठीक करने के लिए एक बड़ी राशि होगी।

ऐसा करने का एकमात्र अन्य तरीका मैं एक कंपाइलर प्लगइन होगा, जैसा कि आप सुझाव देते हैं, और हर पॉइंटर को बनाते हैं संपूर्ण संकलन इकाई संरेखण 1 है।संकलक तब बाइट लोड/स्टोर सब कुछ होगा। यह शायद आपके द्वारा इच्छित कोड से अधिक के लिए ऐसा कर देगा। यह संभवतः हासिल करने के लिए उतना आसान नहीं है जितना लगता है।

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