Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

gcc: link-time substitution

Tags:

c

gcc

linker

i'm currently trying to understand how the gcc Compiler and the Linker are working. I came across a technique called 'link-time substitution' which I find very interesting. The goal is to have multiple definitions of a function in multiple files and to decide which of these definitions goes into the final executable during link time.

A simple example:

main.c:

#include "header.h"

int main(void)
{
    hello("everyone");
    return 0;
}

header.h:

#ifndef _HEADER_H
#define _HEADER_H

void hello(const char * name);

#endif

file1.c:

#include "header.h"
#include <stdio.h>

void hello(const char * name)
{
    printf("File1: Hello, %s!\n", name);
}

file2.c:

#include "header.h"
#include <stdio.h>

void hello(const char * name)
{
    printf("File2: Hello, %s!\n", name);
}

Now I have two questions:

  • Is it possible to select a function by using an appropriate linking order (if all three files appear in the linker's argument list)?
  • Suppose file2.c implements many functions which are needed by main.c. Is it possible to replace a single function or some functions by different implementations in file1.c (with the same name) by using the linker? The linker should at first use the function definitions in file1.c and then use file2.c for the remaining, unresolved functions.

I hope my questions are understandable ;)

Thanks!

like image 685
Athazo Avatar asked Nov 01 '25 01:11

Athazo


1 Answers

Is it possible to select a function by using an appropriate linking order (if all three files appear in the linker's argument list)?

If by "all three files" you mean the object files (and assuming no weak symbols), then no: all 3 files will be linked in, and you will get a duplicate symbol definition error.

But if you put file1.o into lib1.a, and file2.o into lib2.a, then yes:

gcc main.c -l1 -l2  # uses file1.o:hello
gcc main.c -l2 -l1  # uses file2.o:hello

More details here and here.

Suppose file2.c implements many functions which are needed by main.c. Is it possible to replace a single function or some functions by different implementations in file1.c (with the same name) by using the linker?

Yes, but only on platforms that support weak symbols (such as ELF platforms, see __attribute__((weak)) here).

If all symbols in file2.o are defined weakly, and all symbols in file1.o are not, then linking file1.o and file2.o will achieve the desired result: strong symbols win.

I believe (but have not tested) that if both file1.o and file2.o define the same symbols weakly, then the order will matter:

gcc main.c file1.o file2.o  # file1.o definitions override file2.o
gcc main.c file2.o file1.o  # file2.o definitions override file1.o
like image 168
Employed Russian Avatar answered Nov 04 '25 09:11

Employed Russian