আমি কীভাবে একটি এসও ফাইলটিতে প্রতীকগুলি তালিকাভুক্ত করব


485

.So ফাইল থেকে রফতানি করা প্রতীকগুলি কীভাবে আমি তালিকা করব? যদি সম্ভব হয় তবে আমি তাদের উত্সটিও জানতে চাই (উদাহরণস্বরূপ যদি তারা একটি স্ট্যাটিক লাইব্রেরি থেকে টানা হয়)।

আমি জিসিসি ৩.০.২ ব্যবহার করছি, যদি এটি কোনও পার্থক্য করে।


প্ল্যাটফর্মটি একটি পার্থক্য করে। অ্যাপল একটি জিসিসি ৪.০ সরবরাহ করে তবে এটি nmকিছু বিকল্প যেমন, -Dএবং -g(আইআইআরসি) তে সাড়া দেয় না ।
jww

এটি ম্যাক ওএসে কিছুই প্রিন্ট করে না।
ইগোরগানাপলস্কি

3
@jww কারণ এটি বিএসডি nm, জিএনইউ নয় nm
অরেঞ্জডগ

উত্তর:


575

প্রতীক তালিকার জন্য আদর্শ সরঞ্জামটি হ'ল nm, আপনি এটিকে সহজভাবে ব্যবহার করতে পারেন:

nm -gD yourLib.so

আপনি যদি কোনও সি ++ লাইব্রেরির প্রতীক দেখতে চান তবে "-C" বিকল্পটি যুক্ত করুন যা প্রতীকগুলি ডিমেংল করে (এটি আরও বেশি পঠনযোগ্য ডিমেংলড)।

nm -gDC yourLib.so

যদি আপনার .so ফাইলটি এলফ ফর্ম্যাটে থাকে তবে আপনার কাছে দুটি বিকল্প রয়েছে:

হয় objdump( -Cসি ++ ডিমেংলিংয়ের জন্যও কার্যকর):

$ 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
মনে রাখবেন যে এনএম এর ওএস এক্স সংস্করণগুলি প্রতীককে ডিমেংল করার জন্য '-C' বিকল্পটি হারিয়েছে। পরিবর্তে সি ++ ফিল্ট ব্যবহার করা যেতে পারে। উদাহরণ স্ক্রিপ্ট এখানে: v8.googlecode.com/svn/branches/bleeding_edge/tools/mac-nm nm -g /usr/lib/libstdc++.6.dylib | সি ++ ফিল্ট -পি -আই
ফ্রেডবাবা

5
নোট যা readelf -Wsআপনাকে সমস্ত চিহ্ন nm -gদেখায় এবং কেবল বাহ্যিকভাবে দৃশ্যমান প্রতীকগুলি দেখায়। আপনি যদি একাধিক প্রতীক ফাইলগুলি পরীক্ষা করে দেখেন এবং আপনার আদেশগুলি অন্তর্ভুক্ত করেন তবে এটি বিভ্রান্তিকর হতে পারে।
অ্যান্ড্রু বি

3
আমিও objectdump -TCতালিকায় যুক্ত করব। বিপরীতে readelf -Ws, এটি ম্যাঙ্গেল করা নামগুলি দেখায় না।
ইয়ান ফটো

2
@ ব্রুকসমোস .soফাইলগুলির জন্য --dynamicআপনার nmকমান্ড লাইনে যুক্ত হতে পারে ।
ব্যবহারকারী 7610 0

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
পড়ুন -Ws /usr/lib/libstdc++.so.6 | awk '{মুদ্রণ $ 8}'; রেজেক্সস দুর্দান্ত হয় তবে কখনও কখনও কিছুটা বিশ্রী দীর্ঘস্থায়ী হয়।
deft_code


42

ভাগ করা লাইব্রেরির জন্য libNAME.so -D সুইচটি আমার লিনাক্সে প্রতীক দেখতে প্রয়োজনীয় ছিল

nm -D libNAME.so

এবং স্ট্যাটিক লাইব্রেরি হিসাবে অন্যদের দ্বারা রিপোর্ট

nm -g libNAME.a

35

আমি হতাশ রাখা কেন -fvisibility = গোপন এবং #pragma জিসিসি দৃশ্যমানতা কোন প্রভাব আছে বলে মনে হচ্ছে না হিসাবে সব চিহ্ন সবসময় কিভাবে আছে কি NM - যতক্ষণ না আমি এই পোস্টে যে আমার প্রতি ইঙ্গিত পাওয়া readelf এবং objdump , যা আমাকে তৈরি বুঝতে পারছি সেখানে আসলে দুটি প্রতীক টেবিল বলে মনে হচ্ছে :

  • আপনি এনএম দিয়ে তালিকাভুক্ত করতে পারেন
  • আপনি যা পাঠক এবং এজডাম্পের সাথে তালিকাবদ্ধ করতে পারেন

আমি মনে করি পূর্ববর্তীটিতে ডিবাগিং প্রতীক রয়েছে যা আপনি লিঙ্কার বা ইনস্টল কমান্ডকে দিতে পারেন এমন স্ট্রিপ বা -s সুইচ দিয়ে ফেলা যেতে পারে । এমনকি এনএম যদি আর কোনও তালিকা না দেয় তবে আপনার রফতানি প্রতীকগুলি এখনও রফতানি করা হয় কারণ সেগুলি ইএলএফ "গতিশীল প্রতীক টেবিল" এ রয়েছে যা পরেরটি।


3
ধন্যবাদ! এটি ব্যাখ্যা করে যে মাঝে মাঝে "এনএম" .so ফাইলগুলির জন্য কোনও চিহ্ন প্রদর্শন করে না।
ব্রুকস মূসা

10
এনএম-ডি - আপনাকে গতিশীল প্রতীক টেবিলটি
তালিকাবদ্ধ

19

সি ++ .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

প্রতিটি চিহ্নের উত্স পাওয়ার জন্য এনএম পতাকাগুলিতে -l যুক্ত করার চেষ্টা করুন। লাইব্রেরি যদি ডিবাগিং তথ্য (জিসিসি-জি) দিয়ে সংকলিত হয় তবে এটি উত্স ফাইল এবং লাইন নম্বর হওয়া উচিত। কনরাড যেমন বলেছিলেন, অবজেক্ট ফাইল / স্ট্যাটিক লাইব্রেরি সম্ভবত এই সময়ে অজানা।


11

Android এর জন্য .soফাইল, NDK টুলচেইন অন্যান্য উত্তর উল্লেখিত প্রয়োজনীয় সরঞ্জামগুলির সাথে আসে: readelf, objdumpএবং nm


9

আপনি nm -gবাইনুটিস সরঞ্জামচেন থেকে সরঞ্জামটি ব্যবহার করতে পারেন । তবে, তাদের উত্স সর্বদা সহজেই পাওয়া যায় না। এবং আমি আসলেও নিশ্চিত নই যে এই তথ্যটি সর্বদা পুনরুদ্ধার করা যায়। সম্ভবত objcopyআরও তথ্য প্রকাশ।

/ সম্পাদনা: সরঞ্জামটির নাম অবশ্যই nm। পতাকাটি -gকেবল রফতানি প্রতীক দেখানোর জন্য ব্যবহৃত হয়।


6

এনএম -g বাহ্যিক চলক তালিকাবদ্ধ করে, যা প্রয়োজনীয় রফতানি প্রতীক নয় necessary যে কোনও অ স্থিতিশীল ফাইল স্কোপ ভেরিয়েবল (সি তে) সমস্ত বাহ্যিক চলক।

এনএম-ডি গতিশীল টেবিলের মধ্যে প্রতীকটি তালিকাভুক্ত করবে, যা আপনি এটির ঠিকানাটি dlsym দ্বারা খুঁজে পেতে পারেন।

এনএম - রূপান্তর

জিএনইউ এনএম 2.17.50.0.6-12.el5 20061020


1

আপনি যদি কেবল জানতে চান যে উপস্থিত কোনও চিহ্ন রয়েছে তবে আপনি ব্যবহার করতে পারেন

objdump -h /path/to/object

বা ডিবাগ তথ্য তালিকাগুলি

objdump -g /path/to/object
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.