Getting the address of a overwritten weak symbol

335 views Asked by At

My question assumes gcc or clang for x86 or x86_64.

Let's say I have the following files:

// weak.c

#include <stdio.h>

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

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

#include <stdio.h>

void i_am_weak(void)
{
    printf("I am not weak\n");
}

If I compile just weak.c: cc weak.c -o weak and then I run it I get the message "I am weak". In turn, if I compile and link both: cc weak.c not_weak.c I get the message "I am not weak". Which is to be expected.

Can I somehow obtain the address of the weak symbol? Let's say that I want to invoke i_am_weak from weak.c from not_weak.c, similar to how I can use __real_i_am_weak from __wrap_i_am_weak when using the --wrap linker flag.

1

There are 1 answers

1
Employed Russian On BEST ANSWER

Can I somehow obtain the address of the weak symbol?

The usual technique is to use a strong internal symbol, to which i_am_weak is a weak alias (documentation):

#include <stdio.h>

void i_am_internal(void)
{
    printf("I am weak\n");
}

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

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

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

You can now also take address of weak and non-weak symbols.