Как удалить символ из общего объекта?

Как с помощью 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()от до. После того, как foo()удален из a.so, повторный запуск cдолжен сгенерировать распечатку:

0xbeef, 0x0, 0x1

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

nm -a a.so | grep foo

В то время как прямо сейчас он возвращает:

000000000000063c T foo

10
задан Ross Rogers 28 March 2012 в 14:23
поделиться