हां, उदाहरण के लिए अपने स्वयं के निष्पादन योग्य (/proc/self/exe
) की जांच करके वास्तविक प्रतीकों को स्वयं पार्स करने के लिए libbfd
या ईएलएफ फ़ाइल पार्सिंग लाइब्रेरी। अनिवार्य रूप से, आप सी कोड इस तरह
env LANG=C LC_ALL=C readelf -s executable | awk '($5 == "LOCAL" && $8 ~ /^[^_]/ && $8 !~ /\./)'
कुछ के बराबर जहाँ तक मुझे पता के रूप में करता है लिखते हैं, लिनक्स (<dlfcn.h>
) में गतिशील लिंकर इंटरफ़ेस स्थिर (स्थानीय) प्रतीकों के लिए पतों वापस नहीं करता है।
आपके प्रोग्राम से readelf
या objdump
निष्पादित करने के लिए एक सरल और सुंदर मजबूत दृष्टिकोण है। ध्यान दें कि आप उन्हें /proc/self/exe
छद्म-फ़ाइल पथ नहीं दे सकते हैं, क्योंकि यह हमेशा प्रक्रिया को अपने निष्पादन योग्य को संदर्भित करता है। इसके बजाए, आपको उदाहरण का उपयोग करना होगा। वर्तमान निष्पादन योग्य के लिए एक गतिशील आवंटित पूर्ण पथ प्राप्त करने के लिए realpath("/proc/self/exe", NULL)
आप आदेश को आपूर्ति कर सकते हैं। आप निश्चित रूप से यह सुनिश्चित करना चाहते हैं कि पर्यावरण में LANG=C
और LC_ALL=C
शामिल है, ताकि कमांड का आउटपुट आसानी से पारदर्शी हो (और वर्तमान उपयोगकर्ता पसंदीदा भाषा के लिए स्थानीयकृत नहीं है)। यह थोड़ा सा झुकाव महसूस कर सकता है, लेकिन इसे केवल binutils
पैकेज को काम पर स्थापित करने की आवश्यकता है, और आपको नवीनतम कार्यक्रमों को बनाए रखने के लिए अपने प्रोग्राम या लाइब्रेरी को अपडेट करने की आवश्यकता नहीं है, इसलिए मुझे लगता है कि यह समग्र रूप से एक बहुत अच्छा दृष्टिकोण है ।
क्या आपको एक उदाहरण चाहिए?
इसे आसान बनाने का एक तरीका है संकलन समय पर प्रतीक जानकारी के साथ अलग-अलग सरणी उत्पन्न करना। मूल रूप से, के बाद वस्तु फ़ाइलों उत्पन्न कर रहे हैं, एक अलग स्रोत फ़ाइल गतिशील objdump
या readelf
संबंधित वस्तु फ़ाइलों पर चल रहा है, निर्यात एक साधारण खोज समारोह के साथ
const struct {
const char *const name;
const void *const addr;
} local_symbol_names[] = {
/* Filled in using objdump or readelf and awk, for example */
{ NULL, NULL }
};
शायद करने के लिए नाम और संकेत दिए गए समान की एक सरणी पैदा करने से उत्पन्न होता है एक हेडर फ़ाइल में, ताकि अंतिम निष्पादन योग्य लिंक होने पर, यह स्थानीय प्रतीकों की सरणी को आसानी से और कुशलता से एक्सेस कर सके।
यह कुछ डेटा डुप्लिकेट करता है, क्योंकि वही जानकारी पहले ही निष्पादन योग्य फ़ाइल में है, और यदि मुझे सही याद है, तो आपको पहले अंतिम निष्पादन योग्य को प्रतीकों के वास्तविक पते प्राप्त करने के लिए स्टब सरणी से लिंक करना होगा, और फिर प्रतीक सरणी के साथ रिलिकिंक करें, इसे संकलन समय पर परेशानी का थोड़ा सा बना दें .. लेकिन यह binutils
पर रन-टाइम निर्भरता रखने से बचाता है।