2011-05-31 11 views
7

मेरे पास एक साझा लाइब्रेरी (bar.so) के रूप में एक प्लग-इन है जो एक बड़े प्रोग्राम (foo) में लिंक करता है। दोनों foo और bar.so एक ही तीसरे पक्ष की लाइब्रेरी (बाज़) पर निर्भर करते हैं, लेकिन उन्हें बज़ के कार्यान्वयन को पूरी तरह से अलग रखने की आवश्यकता है। तो जब मैं foo को लिंक करता हूं (आपूर्ति की गई ऑब्जेक्ट फ़ाइलों और अभिलेखागारों का उपयोग करके) मुझे बार में बाज़ के किसी भी उपयोग को अनदेखा करने की आवश्यकता होती है। इसके विपरीत और इसके विपरीत।साझा ऑब्जेक्ट में प्रतीकों तक पहुंच प्रतिबंधित कैसे करें?

अभी अगर मैं --trace-symbol=baz_fun साथ foo लिंक जहां baz_fun हमलावर प्रतीकों मैं निम्नलिखित आउटपुट प्राप्त में से एक है:

bar.so: definition of baz_fun 
foo/src.a(baz.o): reference to baz_fun 

मेरा मानना ​​है कि यह कह रहा है कि foo bar.so से baz_fun संदर्भित कर रहा है (और फू का निष्पादन इसकी पुष्टि करता है)।

समाधान है कि मैं कोशिश की है:

  • objcopy का उपयोग करना "स्थानीय बनाना" के हित के लिए प्रतीक: objcopy --localize-symbols=local.syms bar.so जहां local.syms हित के प्रतीकों में से सभी शामिल हैं। मुझे लगता है कि मैं यहां उलझन में हो सकता हूं और शायद "स्थानीय" का मतलब यह नहीं है कि इसका क्या अर्थ है। भले ही, मुझे उपरोक्त लिंक से वही आउटपुट मिलता है। मुझे ध्यान रखना चाहिए कि अगर मैं nm उपकरण को बार पर चलाता हूं। इसलिए objcopy का उपयोग करने से पहले प्रश्न में सभी प्रतीकों में T ध्वज (ऊपरी-केस वैश्विक संकेत) और objcopy के बाद उनके पास t है जो इंगित करता है कि वे अब स्थानीय हैं। तो ऐसा प्रतीत होता है कि मैं objcopy सही तरीके से उपयोग कर रहा हूं।
  • -fvisibility=hidden के साथ संकलन हालांकि कुछ अन्य बाधाओं के कारण मुझे जीसीसी 3.3 का उपयोग करने की आवश्यकता है जो उस सुविधा का समर्थन नहीं करता है। मैं जीसीसी के एक नए संस्करण में अपग्रेड करने में सक्षम हो सकता हूं लेकिन यह पुष्टि करना चाहूंगा कि इस ध्वज से संकलित करने से मुझे उस सड़क पर जाने से पहले मदद मिलेगी।

अन्य बातें ध्यान रखें:

  • मैं या तो foo या baz
  • के स्रोत कोड के लिए पहुँच नहीं है मैं एक साझा वस्तु में मेरी प्लग-इन के सभी रखना पसंद करेंगे (bar.so)। baz वास्तव में एक लाइसेंस पुस्तकालय तो मैं यह

उत्तर

3

उपयोग dlopen अलग RTLD_DEEPBIND ध्वज के साथ अपने प्लगइन लोड करने के लिए नहीं करना चाहती है।

(संपादित करें)

कृपया ध्यान दें कि RTLD_DEEPBIND लिनक्स विशिष्ट है और glibc 2.3.4 या नए की जरूरत है।

+0

शायद मैं गलतफहमी कर रहा हूं, लेकिन अगर मैं अपने प्लगइन को लोड करने वाले foo के स्रोत कोड तक पहुंच नहीं पा रहा हूं, तो मैं यह कैसे कर सकता हूं। Bar.so? – brady

+0

ठीक है अगर आप केवल बार को नियंत्रित करते हैं और foo नहीं करते हैं, तो आप दो पुस्तकालयों, बार 1 और बार 2 में बार विभाजित कर सकते हैं। बार 1 प्लगइन इंटरफ़ेस प्रदान करता है और बाद में सभी कॉल बार 2 प्रदान करता है, और बार 2 सबकुछ लागू करता है। बार 1 को 'dlopen ("libbar2.so", RTLD_NOW | RTLD_DEEPBIND)' और 'dlsym' को आवश्यक सभी कार्यों को कॉल करना चाहिए। या आप एक बार रख सकते हैं, और 'dlopen ("libbaz.so", RTLD_NOW | RTLD_DEEPBIND)' वहां से, और 'dlsym' आपको आवश्यक सभी फ़ंक्शंस' रख सकते हैं। जिस भी विधि को विधि को 'dlsym' पर कम कॉल की आवश्यकता है उसका उपयोग करें। –

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