जीसीसी/एलडी का उपयोग करके, मैं libfoo.a का उपयोग करना चाहता हूं, जिसमें एक प्रतीक symbol_foo है (जो एक फ़ंक्शन है - एक आईएसआर यदि यह मायने रखता है)। libfoo में अन्य फ़ंक्शन स्पष्ट रूप से इस फ़ंक्शन का उपयोग करते हैं। मैं जो करना चाहता हूं वह libfoo.a का उपयोग करके अपनी खुद की बाइनरी संकलित करना है, लेकिन इसके बजाय symbol_foo के अपने संस्करण में लिंक करना है।

क्या यह संभव है? वर्तमान में मुझे प्रतीक की कई परिभाषाओं के कारण एक एलडी त्रुटि मिलती है। अर्थात। इसे मूल स्थिर पुस्तकालय में "सॉफ्ट-लिंक्ड" या ऐसा कुछ भी घोषित नहीं किया गया है।

आदर्श रूप से मैं चाहता हूं कि __attribute__((ld_override)) या जो कुछ भी मौजूद हो, लेकिन मुझे लगता है कि वहां नहीं है। कोई विचार?

3
Benjamin Lindqvist 8 अगस्त 2018, 18:04
आप अपने सिंबल_फू फंक्शन और अन्य फंक्शन दोनों को libfoo.a लाइब्रेरी से प्राप्त करना चाहते हैं?
 – 
Pierre Podevin
8 अगस्त 2018, 18:18
ये मदद कर सकते हैं: stackoverflow.com/questions/ 617554/…
 – 
Pierre Podevin
8 अगस्त 2018, 18:20
नहीं, मैं उनके प्रतीक को ओवरराइड करना चाहता हूं, मेरे द्विआधारी बिंदु में सभी संदर्भों को MINE
 – 
Benjamin Lindqvist
8 अगस्त 2018, 18:22

2 जवाब

सबसे बढ़िया उत्तर

यह पुस्तकालय के डिजाइन पर निर्भर करता है। आपके मामले में, उत्तर "नहीं" है, क्योंकि फ़ंक्शन लाइब्रेरी में अलग नहीं है। पुस्तकालय निर्माण पर एक अच्छी प्रदर्शनी के लिए, पी जे प्लागर देखें मानक C लाइब्रेरी 1992। हां, यह काफी पुराना है, इसलिए मानक C का संस्करण C90 है , लेकिन इसके द्वारा समर्थित विचार अभी भी मान्य हैं।

जब लिंकर एक प्रोग्राम बना रहा होता है, तो वह ऑब्जेक्ट फाइलों और पुस्तकालयों की एक श्रृंखला को संसाधित कर रहा होता है, जो असंतुष्ट संदर्भों (प्रतीक नाम) और ट्रैकिंग परिभाषाओं की तलाश में होता है। अधिकांश परिस्थितियों में, यह प्रतीक main से अपरिभाषित के रूप में शुरू होता है।

  • चूंकि यह किसी ऑब्जेक्ट फ़ाइल को संसाधित करता है, यह नोट करता है कि कौन से प्रतीकों को परिभाषित किया गया है जो एक अपरिभाषित प्रतीक को संतुष्ट करता है और उस फ़ाइल द्वारा परिभाषित सभी नामों को याद रखता है (और यह शिकायत करता है कि प्रतीकों में से एक के साथ संघर्ष होता है जिसे वह पहले से जानता है)।
  • चूंकि यह एक स्थिर पुस्तकालय को संसाधित करता है, यह उन प्रतीकों की तलाश करता है जिन्हें परिभाषित किया गया है कि इसकी पहले से कोई परिभाषा नहीं है। जब यह ऐसा प्रतीक पाता है, तो यह पुस्तकालय से ऑब्जेक्ट फ़ाइल को जोड़ता है, यह देखते हुए कि कौन से प्रतीकों को परिभाषित किया गया है और जो अभी भी अपरिभाषित हैं।

अब, यदि symbol_foo वाली ऑब्जेक्ट फ़ाइल केवल symbol_foo को परिभाषित करती है, तो यदि आपने अपने symbol_foo को लाइब्रेरी पढ़ने से पहले लिंक कर दिया है, तो लिंकर symbol_foo को अनदेखा कर देगा। पुस्तकालय; इसकी पहले से ही एक परिभाषा है और दूसरे की आवश्यकता नहीं है। हालांकि, यह संभव है कि libfoo.a लाइब्रेरी में symbol_foo वाली ऑब्जेक्ट फ़ाइल कुछ अन्य प्रतीकों को भी परिभाषित करती है, और उन अन्य प्रतीकों की आवश्यकता लिंकर को होती है, इसलिए इसे ऑब्जेक्ट फ़ाइल को लिंक करना होगा जिसमें symbol_foo, और शिकायत करता है क्योंकि वह प्रतीक दोगुना परिभाषित है, भले ही उसी फ़ाइल में अन्य नहीं हैं।

प्लॉगर इस बात की वकालत करता है कि एक (स्थिर) पुस्तकालय में प्रत्येक वस्तु फ़ाइल को एक बाहरी प्रतीक को परिभाषित करना चाहिए। यह पुस्तकालय में कार्यों के लिए अधिकतम प्रतिस्थापन क्षमता की अनुमति देता है। मेरा मानना ​​है कि यह मान लेना उचित है कि libfoo.a के डिजाइनर ने कम से कम w.r.t symbol_foo, वह निर्णय नहीं लिया।

आप ऑब्जेक्ट फ़ाइलों को libfoo.a से निकाल सकते हैं (एक अस्थायी निर्देशिका का उपयोग करें) और nm के साथ उनकी सामग्री की जांच करें; आप इसे सीधे पुस्तकालय पर ही करने में सक्षम हो सकते हैं। उचित विकल्पों के साथ प्रयोग किया जाता है, जो आपको दिखाएगा कि कौन सी फाइलें परिभाषित करती हैं और अन्य प्रतीकों का संदर्भ देती हैं।

ध्यान दें कि साझा पुस्तकालयों से जोड़ने के नियम कुछ अलग हैं। ऐसे 'कमजोर' प्रतीक भी हैं जो व्यवहार को बदल सकते हैं। आप अक्सर कई ऑब्जेक्ट फ़ाइलों (ld -r आमतौर पर) से 'स्थानांतरित करने योग्य' या 'रिलिंक करने योग्य' ऑब्जेक्ट फ़ाइलें भी बना सकते हैं; जो आपको एक बड़ी ऑब्जेक्ट फ़ाइल देता है और समीकरण को बदल देता है। अंत में, अभी के लिए, लिंकर स्क्रिप्ट नियंत्रित कर सकती हैं कि कौन से प्रतीक पुस्तकालय के बाहर दिखाई दे रहे हैं। तो, यह विषय पर एक चमक से ज्यादा कुछ नहीं है।

5
Jonathan Leffler 8 अगस्त 2018, 18:39
हां, मैंने वास्तव में objdump --assemble-all का उपयोग करके योगिनी की जांच की। मुझे यह अजीब लगता है कि फिर से जोड़ना पूर्ववत होना चाहिए, क्योंकि यह बल-इनलाइन या ऐसा कुछ भी नहीं दिखता है। मेरा मतलब है कि सैद्धांतिक रूप से मैं dd भी कर सकता हूं - अंतिम बाइनरी (एनओपी के साथ पैडिंग) को हॉटपैच कर सकता हूं। अजीब लगता है कि हालांकि एक क्लीनर तरीका मौजूद नहीं होना चाहिए ..
 – 
Benjamin Lindqvist
8 अगस्त 2018, 19:32

एक सामान्य नियम के रूप में, यदि आप एक स्थिर पुस्तकालय में एक गैर-कमजोर, वैश्विक प्रतीक को ओवरराइड (प्रतिस्थापित) करना चाहते हैं और फिर भी बाकी पुस्तकालय का उपयोग करना चाहते हैं, तो आपको अन्य सभी गैर-कमजोर, वैश्विक को बदलने की भी आवश्यकता होगी स्थिर मुक्ति में एक ही संकलन इकाई में प्रतीक।

आप पुस्तकालय में सभी प्रतीकों को nm के साथ पा सकते हैं - चल रहा
nm libfoo.a | grep ' [BDGRST] \|:' पुस्तकालय में प्रत्येक वस्तु (संकलन इकाई) को सूचीबद्ध करेगा, उसके बाद सभी गैर-कमजोर वैश्विक प्रतीकों को सूचीबद्ध करेगा। वस्तु।

0
Chris Dodd 8 अगस्त 2018, 19:51