Мой ответ относится к комбинации ошибок hidden symbol (...) is referenced by DSO
и Nonrepresentable section on output
.
Краткий ответ: символ был помечен extern
, но также помечен как скрытый (см. Видимость (вики GCC) и Как писать общие библиотеки (Ульрих Дреппер) ). Никакие объекты или архивы не были связаны для удовлетворения зависимости, но общий объект был связан с соответствующим символом.
Вы, вероятно, скомпилированы с -fvisibility=hidden
, и независимо от того, была ли это добавленная компилятором функция (например, стековая защита) или что-то еще, символ, испускаемый в вашем коде, перекрывал видимость по умолчанию неопределенной ссылки на символ с тем же именем libc_nonshared.a
, который обычно удовлетворяется libc.so
.
Вы можете воспроизвести похожую проблему следующим образом:
#include <stdio.h>
extern __attribute__((visibility ("hidden")))
FILE* open_memstream( char**, size_t* );
char* asdf;
size_t mysize;
FILE* blah() {
return open_memstream( &asdf, &mysize );
}
... затем его компилировать:
# with gcc 4.9.2:
~ gcc badcode.c -shared -fPIC -o libbad.so -lc
/tmp/ccC0uG80.o: In function `blah':
badcode.c:(.text+0x19): undefined reference to `open_memstream'
/usr/bin/ld: /tmp/libbad.so: hidden symbol `open_memstream' isn't defined
/usr/bin/ld: final link failed: Bad value
# with gcc 4.4.7:
~ gcc badcode.c -shared -fPIC -o libbad.so -lc
/tmp/cc2SHUFD.o: In function `blah':
badcode.c:(.text+0x26): undefined reference to `open_memstream'
/usr/bin/ld: /tmp/libbad.so: hidden symbol `open_memstream' isn't defined
/usr/bin/ld: final link failed: Nonrepresentable section on output
# with oracle solaris studio (still in Linux) 12.3:
~ cc -shared -Kpic -o /tmp/libbad.so badcode.c -lc
badcode.o: In function `blah':
badcode.c:(.text+0x32): undefined reference to `open_memstream'
/usr/bin/ld: /tmp/libbad.so: hidden symbol `open_memstream' isn't defined
/usr/bin/ld: final link failed: Nonrepresentable section on output
Короче говоря: я заранее объявил о существовании символа, пометил его как скрытый, а затем не связал в статической библиотеке или объектном файле, который удовлетворял зависимости. Поскольку он помечен как скрытый, зависимость должна быть удовлетворена, в противном случае это недопустимый объект ELF.
В моем конкретном случае заголовок шел по неверному пути #if
и вызывал вышеуказанное скрытое объявление open_memstream
.