Получение адреса перезаписанного слабого символа

#c #linker #weak-linking

#c #компоновщик #слабая связь

Вопрос:

Мой вопрос предполагает gcc или clang для x86 или x86_64.

Допустим, у меня есть следующие файлы:

 // weak.c

#include <stdio.h>

__attribute__((weak))
void i_am_weak(void)
{
    printf("I am weakn");
}

int main()
{
    i_am_weak();
    return 0;
}
  
 // not_weak.c

#include <stdio.h>

void i_am_weak(void)
{
    printf("I am not weakn");
}
  

Если я просто скомпилирую weak.c : cc weak.c -o weak и затем я его запускаю, я получаю сообщение «Я слаб». В свою очередь, если я скомпилирую и свяжу оба: cc weak.c not_weak.c я получаю сообщение «Я не слабый». Чего и следовало ожидать.

Могу ли я каким-либо образом получить адрес слабого символа? Допустим, я хочу вызвать i_am_weak from weak.c from not_weak.c , аналогично тому, как я могу использовать __real_i_am_weak from __wrap_i_am_weak при использовании флага --wrap компоновщика.

Ответ №1:

Могу ли я каким-либо образом получить адрес слабого символа?

Обычный метод заключается в использовании сильного внутреннего символа, к которому i_am_weak относится слабый псевдоним (документация):

 #include <stdio.h>

void i_am_internal(void)
{
    printf("I am weakn");
}

void i_am_weak(void) __attribute__((weak, alias("i_am_internal"))) 

int main()
{
    i_am_weak();
    i_am_internal();
    return 0;
}
  
 $ gcc weak.c amp;amp; ./a.out
I am weak
I am weak

$ gcc weak.c not_weak.c amp;amp; ./a.out
I am not weak
I am weak
  

Теперь вы также можете получать адреса слабых и неслабых символов.

Комментарии:

1. Итак, если бы у меня были такие ситуации pastebin.com/wZH7JZr7 и я хотел заменить dependency_of_tested_function во время тестирования, но иногда я хотел бы динамически контролировать, какая функция вызывается, и в итоге получалось бы что-то вроде этого pastebin.com/7wTaCrkJ Спасибо 🙂