
Continuons cette série sur les codes fantastiques avec une optimisation inattendue de l’éditeur de liens.
Étudions, si vous le voulez bien, ce petit code C :
Rien de bien affolant, et de fait, c’est sa forme compilée qui nous intéresse, passons un coup de gcc -O2 petit_code.c -o petit dessus, puis inspectons le binaire avec objdump -S petit :
Ce qui nous intéresse ici, ce sont les arguments de puts : deux chaînes distinctes présentes aux adresses $0x402016 et $0x402010. Regardons le contenu de la section .rodata avec objdump -s -j .rodata petit_code :
Ô joie, on retrouve à l’adresse 0x402010 notre chaîne "hello world", mais ô tristesse, rien pour la chaîne "world". On observe cependant que 0x402016 = 0x402010 + strlen("hello "), l’éditeur de liens a en fait appliqué une optimisation nommée suffix merging.
Le suffix merging est une optimisation de l’éditeur de liens qui consiste à fusionner l’espace de stockage de plusieurs chaînes quand elles sont suffixes les unes des autres, et de juste faire pointer l’adresse du symbole associé au bon endroit dans cet espace de stockage commun. Simple, élégant et efficace ! Les éditeurs de liens gold, bfd et lld appliquent tous cette optimisation.
La session suivante illustre l’optimisation avec des symboles explicites :
Bien évidemment, cette optimisation n’est valable que sur les chaînes constantes, sinon la propriété de suffixe pourrait varier dans le temps. Et comme elle est appliquée par l’éditeur de liens, elle permet de fusionner des chaînes qui sont dans des unités de compilation différentes.
Ça vous intrigue ? Alors peut-être devriez-vous vous intéresser à une autre optimisation du compilateur qui fait intervenir l’éditeur de liens : -fmerge-constants. Et pourquoi pas, regarder également l’option --icf de l’éditeur de liens, qui est dans la même veine ? On a tendance à penser compilateur quand on parle d’optimisation de code, mais l’éditeur de liens aussi a son rôle à jouer !