Мне нужно связать программу C с общим объектом без заголовков разделов.
-
22-09-2019 - |
Вопрос
Я написал интерфейс генератора кода, который позволяет мне создавать общие объекты.Хотя я не хочу реализовывать поддержку таблицы заголовков разделов, потому что именно здесь остается основная сложность формата файла 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.Если в вашем генераторе есть работающий механизм динамического связывания, ему потребуется вся та же информация, что и та, которую вы вставляете в таблицы разделов.
Из-за лени я написал общий файл сборки и использовал для него команду Strip, чтобы получить контрольную точку.«readelf --sections» показывает несколько разделов, но они вам не нужны.Я работал над этим и реализовал разделы по порядку, пока все не начало работать правильно.Вот что мне пришлось добавить:
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.Я не уверен, что это сделает тебя счастливым.