मैं .so फ़ाइल में प्रतीकों को कैसे सूचीबद्ध करूं


485

मैं .so फ़ाइल से निर्यात किए जा रहे प्रतीकों को कैसे सूचीबद्ध करूं? यदि संभव हो तो, मैं उनका स्रोत भी जानना चाहूंगा (जैसे कि उन्हें किसी स्थैतिक पुस्तकालय से निकाला जाए)।

मैं gcc 4.0.2 का उपयोग कर रहा हूँ, अगर इससे कोई फर्क पड़ता है।


मंच पर फर्क पड़ता है। Apple एक GCC 4.0 प्रदान करता है, लेकिन इसके nmकुछ विकल्पों का जवाब नहीं देता है, जैसे -Dऔर -g(IIRC)।
jww

यह मैक ओएस पर कुछ भी प्रिंट नहीं करता है।
इगोरगानापोलस्की

3
@jww क्योंकि वह BSD है nm, GNU नहीं nm
ऑरेंजडॉग

जवाबों:


575

प्रतीकों को सूचीबद्ध करने के लिए मानक उपकरण है nm, आप इसे इस तरह से उपयोग कर सकते हैं:

nm -gD yourLib.so

यदि आप C ++ लाइब्रेरी के प्रतीकों को देखना चाहते हैं, तो "-C" विकल्प जोड़ें जो प्रतीकों को व्यवस्थित करता है (यह कहीं अधिक पठनीय ध्वस्त है)।

nm -gDC yourLib.so

यदि आपकी .so फ़ाइल योगिनी प्रारूप में है, तो आपके पास दो विकल्प हैं:

या तो objdump( -CC ++ को गिराने के लिए भी उपयोगी है):

$ objdump -TC libz.so

libz.so:     file format elf64-x86-64

DYNAMIC SYMBOL TABLE:
0000000000002010 l    d  .init  0000000000000000              .init
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.2.5 free
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.2.5 __errno_location
0000000000000000  w   D  *UND*  0000000000000000              _ITM_deregisterTMCloneTable

या उपयोग करें readelf:

$ readelf -Ws libz.so
Symbol table '.dynsym' contains 112 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000002010     0 SECTION LOCAL  DEFAULT   10
     2: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND free@GLIBC_2.2.5 (14)
     3: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __errno_location@GLIBC_2.2.5 (14)
     4: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_deregisterTMCloneTable

35
यह हमेशा .so फ़ाइलों के साथ काम नहीं करता है, हालांकि, और इसलिए आपको दूसरे उत्तर में वर्णित "रीडफ़्ल" समाधान का उपयोग करना पड़ सकता है।
ब्रूक्स मूसा

9
ध्यान दें कि nm के OS X संस्करण प्रतीकों को गिराने के लिए '-C' विकल्प को याद नहीं कर रहे हैं। इसके बजाय c ++ filt का उपयोग किया जा सकता है। उदाहरण लिपि यहाँ: v8.googlecode.com/svn/branches/bleeding_edge/tools/mac-nm nm -g /usr/lib/libstdc++.6.dylib | c ++ filt -p -i
fredbaba

5
ध्यान दें कि readelf -Wsआप सभी प्रतीकों को दिखाएंगे , और nm -gकेवल बाहरी रूप से दिखाई देने वाले प्रतीकों को दिखाएगा । यदि आप कई प्रतीक फाइलों की जांच कर रहे हैं और अपने आदेशों को बदलना शुरू कर रहे हैं तो यह भ्रामक हो सकता है।
एंड्रयू बी

3
मैं भी objectdump -TCसूची में जोड़ना होगा । इसके विपरीत readelf -Ws, यह आम नाम नहीं दिखाता है।
यान फोटो

2
के लिए @BrooksMoses .soफ़ाइलों को आप जोड़ना पड़ सकता है --dynamicकरने के लिए nmकमांड लाइन।
user7610

84

यदि आपकी .soफ़ाइल योगिनी प्रारूप में है, तो आप बाइनरी से प्रतीक जानकारी निकालने के लिए रीडफुल प्रोग्राम का उपयोग कर सकते हैं। यह कमांड आपको प्रतीक तालिका देगा:

readelf -Ws /usr/lib/libexample.so

आपको केवल उन लोगों को निकालना चाहिए जो इस .soफ़ाइल में परिभाषित हैं , न कि इसके द्वारा संदर्भित पुस्तकालयों में। इस मामले में सातवें कॉलम में एक नंबर होना चाहिए। आप एक साधारण रेगेक्स का उपयोग करके इसे निकाल सकते हैं:

readelf -Ws /usr/lib/libstdc++.so.6 | grep '^\([[:space:]]\+[^[:space:]]\+\)\{6\}[[:space:]]\+[[:digit:]]\+'

या, कैस्पिन द्वारा प्रस्तावित :

readelf -Ws /usr/lib/libstdc++.so.6 | awk '{print $8}';

19
readelf -Ws /usr/lib/libstdc++.so.6 | awk '{प्रिंट $ 8}'; regexes कमाल के हैं लेकिन कभी-कभी थोड़ा सा जागना एक लंबा रास्ता तय करता है।
deft_code


42

साझा पुस्तकालयों के लिए libNAME.so -D स्विच मेरे लिनक्स में प्रतीकों को देखने के लिए आवश्यक था

nm -D libNAME.so

और दूसरों के द्वारा बताई गई स्थिर लाइब्रेरी के लिए

nm -g libNAME.a

35

मैं सोचता रहा कि क्यों -फिजिबिलिटी = छिपी हुई है और #pragma GCC दृश्यता का कोई प्रभाव नहीं दिख रहा है, क्योंकि सभी प्रतीक हमेशा nm के साथ दिखाई देते थे - जब तक मुझे यह पोस्ट नहीं मिली जो मुझे खुद को पढ़ने और देखने के लिए प्रेरित करता था , जिससे मुझे एहसास हुआ कि वहाँ वास्तव में दो प्रतीक तालिकाओं लगते हैं :

  • जिसे आप nm से सूचीबद्ध कर सकते हैं
  • एक आप के साथ सूचीबद्ध कर सकते हैं readelf और objdump

मुझे लगता है कि पूर्व में डिबगिंग प्रतीक शामिल हैं जिन्हें पट्टी या -s स्विच से हटाया जा सकता है जिसे आप लिंकर या इंस्टॉल कमांड को दे सकते हैं । और भले ही एनएम अब कुछ भी सूचीबद्ध नहीं करता है, आपके निर्यात किए गए प्रतीकों को अभी भी निर्यात किया जाता है क्योंकि वे ईएलएफ "डायनेमिक प्रतीक तालिका" में हैं, जो बाद का है।


3
धन्यवाद! यह बताता है कि कभी-कभी "nm" .so फ़ाइलों के लिए कोई प्रतीक क्यों नहीं दिखाता है।
ब्रूक्स मूसा

10
एनएम-डी - आपको डायनामिक सिंबल टेबल
pt123

19

C ++ .soफ़ाइलों के लिए, अंतिम nmआदेश हैnm --demangle --dynamic --defined-only --extern-only <my.so>

# nm --demangle --dynamic --defined-only --extern-only /usr/lib64/libqpid-proton-cpp.so | grep work | grep add
0000000000049500 T proton::work_queue::add(proton::internal::v03::work)
0000000000049580 T proton::work_queue::add(proton::void_function0&)
000000000002e7b0 W proton::work_queue::impl::add_void(proton::internal::v03::work)
000000000002b1f0 T proton::container::impl::add_work_queue()
000000000002dc50 T proton::container::impl::container_work_queue::add(proton::internal::v03::work)
000000000002db60 T proton::container::impl::connection_work_queue::add(proton::internal::v03::work)

स्रोत: https://stackoverflow.com/a/43257338


11

प्रत्येक प्रतीक के स्रोत को प्राप्त करने के लिए n-झंडे को -l जोड़ने का प्रयास करें। यदि लाइब्रेरी डिबगिंग जानकारी (gcc -g) के साथ संकलित है, तो यह स्रोत फ़ाइल और लाइन नंबर होना चाहिए। जैसा कि कोनराड ने कहा, ऑब्जेक्ट फ़ाइल / स्टेटिक लाइब्रेरी इस बिंदु पर शायद अज्ञात है।


11

Android के लिए .soफ़ाइलें, NDK toolchain अन्य उत्तर में उल्लेख आवश्यक उपकरणों के साथ आता है: readelf, objdumpऔर nm


9

आप nm -gउपकरण का उपयोग बिन्यूटिल्स टूलचिन से कर सकते हैं । हालांकि, उनका स्रोत हमेशा आसानी से उपलब्ध नहीं होता है। और मुझे वास्तव में भी यकीन नहीं है कि यह जानकारी हमेशा पुनर्प्राप्त की जा सकती है। शायद objcopyआगे की जानकारी का पता चलता है।

/ EDIT: उपकरण का नाम बेशक है nm। ध्वज -gका उपयोग केवल निर्यात किए गए प्रतीकों को दिखाने के लिए किया जाता है।


6

nm -g बाहरी वेरिएबल को सूचीबद्ध करता है, जो आवश्यक निर्यात प्रतीक नहीं है। कोई भी गैर-स्थिर फ़ाइल स्कोप वैरिएबल (C में) सभी एक्सटर्नल वैरिएबल हैं।

nm -D प्रतीक को डायनेमिक टेबल में सूचीबद्ध करेगा, जिसे आप dlsym द्वारा पता कर सकते हैं।

nm --version

जीएनयू एनएम 2.17.50.0.6-12.el5 20061020


1

यदि आप केवल जानना चाहते हैं कि क्या प्रतीक मौजूद हैं तो आप उपयोग कर सकते हैं

objdump -h /path/to/object

या डीबग जानकारी को सूचीबद्ध करने के लिए

objdump -g /path/to/object
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.