Как я могу удалить символ из общего объекта? - PullRequest
10 голосов
/ 28 марта 2012

Используя GCC, как я могу удалить символ из общего объекта после того, как я создал общий объект?Если у меня есть три файла в C, манипулирующих символом foo(), например:

// a.c
int foo() { return 0xdead; }
int baz() { return 1; }

и

// b.c
int foo() { return 0xbeef; }
int bar() { return 0; }

и

// c.c
#include "stdio.h"
extern int foo();
extern int bar();
extern int baz();
int main() { printf("0x%x, 0x%x, 0x%x\n",foo(),bar(),baz()); return 0; }

Затем я компилирую и запускаю как:

% gcc a.c --shared -fPIC -o a.so
% gcc b.c --shared -fPIC -o b.so
% setenv LD_LIBRARY_PATH . # export LD_LIBRARY_PATH=. for bash systems
% gcc c.c a.so b.so -o c
% ./c
0xdead, 0x0, 0x1

Как сделать так, чтобы a.so больше не имел символа foo() после того, как я создал a.so?Я хочу, чтобы foo(), определенный в b.so, использовался вместо a.so , удаляя символ foo() из a.so.После удаления foo() из a.so повторный запуск c должен сгенерировать распечатку:

0xbeef, 0x0, 0x1

В этом примере с игрушкой я знаю, что могу просто переупорядочить имена библиотек при компиляции c.c с a.so и b.so, но как я могу фактически удалить символ из a.so?Я представляю, что после удаления foo() из a.so этот grep вывода nm ничего не даст:

nm -a a.so | grep foo

Тогда как сейчас он возвращает:

000000000000063c T foo

Ответы [ 2 ]

14 голосов
/ 28 марта 2012

Вы можете использовать опцию -N (--strip-symbol), равную objcopy , чтобы достичь желаемого:

$ objcopy -N foo a.so
2 голосов
/ 28 марта 2012

Видимость символов выглядит как превосходное решение, позволяющее выбрать, какие функции предназначены для связывания во время выполнения, а какие локальны для библиотеки, но все еще объявлены как «extern», чтобы разрешить использование из других файлов .c, входящих в библиотеку - http://gcc.gnu.org/wiki/Visibility.

...