أحتاج إلى ربط برنامج C على كائن مشترك بدون رؤوس قسم

StackOverflow https://stackoverflow.com/questions/2127638

سؤال

لقد كتبت واجهة إلى مولد الرمز الذي يتيح لي إنتاج كائنات مشتركة. على الرغم من أنني لا أرغب في تنفيذ الدعم لجدول رأس القسم لأن هذا هو المكان الذي يبقى فيه تعقيد غالبية تنسيق ملف ELF.

يستخدم GNU LD رؤوس القسم للربط مع الكائنات المشتركة. هذا يعني أنه عندما أحاول وضع رابط GCC مع كائني المشترك بدون رؤوس قسم ، فسوف يفشل لأن LD لا يجد الرموز حتى لو كانت موجودة في المكتبة.

هل توجد بعض الخدعة التي يمكنني استخدامها لخداع المترجم لجعل الارتباط ينجح حتى لو لم يجد رموزًا معينة؟

إليك بعض التوضيح حول المشكلة:

cheery@ruttunen:~/Documents/g386$ gcc dev/shared_test.c -L. -lshared -m32
/tmp/cc6qBViY.o: In function `main':
shared_test.c:(.text+0xa): undefined reference to `example_function'
collect2: ld returned 1 exit status
cheery@ruttunen:~/Documents/g386$ cat dev/shared_test.c 
// gcc shared_test.c -L. -lshared -m32
// LD_LIBRARY_PATH=. ./a.out
#include <stdio.h>

extern int example_function();

int main(){
    printf("hello %d\n", example_function());
}
cheery@ruttunen:~/Documents/g386$ readelf -D -s libshared.so 

Symbol table for image:
  Num Buc:    Value  Size   Type   Bind Vis      Ndx Name
    2   0: 00800164     0    FUNC GLOBAL DEFAULT ABS example_function
    1   0: 008000ac     0  OBJECT GLOBAL DEFAULT ABS _DYNAMIC
هل كانت مفيدة؟

المحلول 2

أفضل نهج هنا هو إضافة جداول القسم المطلوبة بواسطة GCC. إذا كان لديك آلية ارتباط ديناميكية عاملة في مولدك ، فهذا يتطلب كل المعلومات نفسها مثل ما ستقدمه في جداول الأقسام.

من أجل الكسل ، كتبت ملف تجميع مشترك واستخدمه في الشريط للحصول على نقطة مرجعية. ´Readelf -يظهر المقاطعان قسمين لكنك لا تحتاج إلى كل شيء. عملت من خلال هذا وقمت بتنفيذ الأقسام بالترتيب حتى بدأت العمل بشكل صحيح. هذا ما اضطررت لإضافته:

cheery@ruttunen:~/Documents/g386$ readelf --sections dynamic_hello.app 
There are 5 section headers, starting at offset 0x1b9:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .shstrndx         STRTAB          00000000 000281 000024 00      0   0  1
  [ 2] .dynamic          DYNAMIC         00000000 0000b0 000050 08  WA  3   0  4
  [ 3] .dynstr           STRTAB          00000000 000158 000020 00   A  0   0  1
  [ 4] .dynsym           DYNSYM          00000000 000100 000040 10   A  3   0  4
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

لا يضر إذا وضعت أقسامًا أكثر من هذه ، ولكن هذا يكفي للحصول على ربط ديناميكي.

نصائح أخرى

لدى GCC (أي ، LD خلف GCC) خيار سطر الأوامر لتجاهل العوامل الخارجية التي لم يتم حلها. سوف تقمع رسالة الخطأ التي تحصل عليها من GCC. لست متأكدًا من أن هذا سيجعلك سعيدًا.

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