سؤال

كيف أقوم بإدراج الرموز التي يتم تصديرها من ملف .so؟إذا أمكن، أود أيضًا معرفة مصدرهم (على سبيل المثال:إذا تم سحبها من مكتبة ثابتة).

أنا أستخدم gcc 4.0.2، إذا كان ذلك يحدث فرقًا.

هل كانت مفيدة؟

المحلول

الأداة القياسية لإدراج الرموز هي nm, ، يمكنك استخدامه ببساطة مثل هذا:

nm -g yourLib.so

إذا كنت تريد رؤية رموز مكتبة C++، أضف الخيار "-C" الذي يزيل تشابك الرموز (وهو أكثر قابلية للقراءة).

nm -gC yourLib.so

إذا كان ملف .so الخاص بك بتنسيق elf، فلديك خياران:

أيضاً objdump (-C مفيد أيضًا في فك تشفير 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

نصائح أخرى

إذا كان لديك .so الملف بتنسيق elf، يمكنك استخدام برنامج readelf لاستخراج معلومات الرمز من الملف الثنائي.سيعطيك هذا الأمر جدول الرموز:

readelf -Ws /usr/lib/libexample.so

يجب عليك فقط استخراج تلك المحددة في هذا .so الملف، وليس في المكتبات المشار إليها به.يجب أن يحتوي العمود السابع على رقم في هذه الحالة.يمكنك استخراجه باستخدام regex بسيط:

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

أو كما اقترح كاسبين,:

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

بالنسبة للمكتبات المشتركة libNAME.so، كان مفتاح التبديل -D ضروريًا لرؤية الرموز في نظام Linux الخاص بي

nm -D libNAME.so

وللمكتبة الثابتة كما أفاد آخرون

nm -g libNAME.a

ظللت أتساءل لماذا -fvisibility=خفية و #pragma رؤية دول مجلس التعاون الخليجي لا يبدو أن لها أي تأثير، حيث كانت جميع الرموز مرئية دائمًا نانومتر - حتى وجدت هذا المنشور الذي دلني عليه readelf و com.objdump, مما جعلني أدرك أنه يبدو أن هناك بالفعل اثنين جداول الرموز:

  • الشخص الذي يمكنك القائمة معه نانومتر
  • الشخص الذي يمكنك القائمة معه readelf و com.objdump

أعتقد أن الأول يحتوي على رموز تصحيح يمكن تجريدها يجرد أو رمز التبديل -s الذي يمكنك منحه للرابط أو ثَبَّتَ يأمر.وحتى إذا لم يعد nm يُدرج أي شيء، فسيستمر تصدير الرموز المصدرة الخاصة بك لأنها موجودة في "جدول الرموز الديناميكي" الخاص بـ ELF، وهو الأخير.

حاول إضافة -l إلى إشارات nm للحصول على مصدر كل رمز.إذا تم تجميع المكتبة بمعلومات تصحيح الأخطاء (gcc -g)، فيجب أن يكون هذا هو الملف المصدر ورقم السطر.كما قال كونراد، ربما يكون ملف الكائن/المكتبة الثابتة غير معروف في هذه المرحلة.

لأجهزة الأندرويد .so الملفات، تأتي سلسلة أدوات NDK مع الأدوات المطلوبة المذكورة في الإجابات الأخرى: readelf, objdump و nm.

لسي ++ .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

يمكنك استخدام ال nm -g أداة من سلسلة أدوات binutils.ومع ذلك، فإن مصدرها ليس متاحًا دائمًا بسهولة.ولست متأكدًا في الواقع من إمكانية استرجاع هذه المعلومات دائمًا.ربما objcopy يكشف المزيد من المعلومات.

/يحرر:اسم الاداة بالطبع nm.العلم -g يستخدم لإظهار الرموز المصدرة فقط.

nm -g يسرد المتغير الخارجي، وهو ليس رمزًا مُصدَّرًا ضروريًا.أي متغير نطاق ملف غير ثابت (في C) كلها متغيرات خارجية.

سوف يقوم nm -D بإدراج الرمز في الجدول الديناميكي، والذي يمكنك العثور على عنوانه عن طريق dlsym.

نانومتر - الإصدار

جنو نانومتر 2.17.50.0.6-12.el5 20061020

إذا كنت تريد فقط معرفة ما إذا كانت هناك رموز حاضر يمكنك استخدام

objdump -h /path/to/object

أو لسرد معلومات التصحيح

objdump -g /path/to/object
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top