Les codes fantastiques : fusion en chaîne

Magazine
Marque
GNU/Linux Magazine
Numéro
275
Mois de parution
mai 2025
Spécialité(s)


Résumé

Continuons cette série sur les codes fantastiques avec une optimisation inattendue de l’éditeur de liens.


Body

Étudions, si vous le voulez bien, ce petit code C :

#include <stdio.h>
int main() {
  puts("hello");
  puts("hello world");
  return 0;
}

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 :

0000000000401040 <main>:
  401040:    48 83 ec 08              sub    $0x8,%rsp
  401044:    bf 16 20 40 00           mov    $0x402016,%edi
  401049:    e8 e2 ff ff ff           call   401030 <puts@plt>
  40104e:    bf 10 20 40 00           mov    $0x402010,%edi
  401053:    e8 d8 ff ff ff           call   401030 <puts@plt>
  401058:    31 c0                    xor    %eax,%eax
  40105a:    48 83 c4 08              add    $0x8,%rsp
  40105e:    c3                       ret
  40105f:    90                       nop

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 :

Contents of section .rodata:
402000 01000200 00000000 00000000 00000000 ................
402010 68656c6c 6f20776f 726c6400           hello world.

Ô 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 :

$ cat b.c
const char A[] = "world";
const char B[] = "hello world";
$ gcc -O2 b.c -shared -o b.so
$ nm -D b.so # -D
000000000000200c R A
0000000000002000 R B

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 !



Article rédigé par

Par le(s) même(s) auteur(s)

C sans frontières : une extension de C avec vérification de bornes

Magazine
Marque
MISC
Numéro
143
Mois de parution
janvier 2026
Spécialité(s)
Résumé

D’aucuns penseraient que le langage C est un langage simple. Après tout le fameux Kernighan & Ritchie de 1978 (a.k.a. White Book) ne fait que 200 pages, bien peu pour un langage qui a servi de base au noyau Linux, au compilateur GCC et à l’interpréteur de référence de Python, CPython. Et pourtant s’il y a bien une notion parmi toutes celles introduites dans the White Book qui met au défi ingénieurs en sécurité, chercheurs en compilation et développeurs en tout genre, c’est la notion de pointeur, et cette terrible question : le déréférencement de mon pointeur donne-t-il lieu à un comportement indéfini ?Des ingénieurs de chez Apple ont trouvé un chemin pragmatique et intéressant à cette question, et ils l’ont mis à disposition dans un fork de clang à travers une option, -fbounds-safety, et un fichier d’en-tête, <ptrcheck.h>. Examinons leur approche.

C++ : contrôlez votre espérance de vie

Magazine
Marque
MISC
Numéro
141
Mois de parution
septembre 2025
Spécialité(s)
Résumé

Le langage C est un magnifique outil pédagogique pour enseigner le concept de mémoire, puisqu’il laisse la main au développeur pour la gérer. Mais on le sait, cet attrait n’en est pas un quand on parle de sûreté d’exécution, puisque ce langage est connu pour ne pas aider le développeur pour détecter les usages illégaux liés à la mémoire. Le langage Rust a attaqué le problème en rendant explicite le concept de durée de vie. Le langage Safe C++ tente quant à lui d’introduire ce concept en C++. Il y a plus de vingt ans, splint proposait déjà un concept moins ambitieux pour C. Et maintenant certains fous essaient de le porter vers C++, à travers des extensions de Clang. Quelles sont donc toutes ces approches ?

Les listes de lecture

Python niveau débutant

9 article(s) - ajoutée le 01/07/2020
Vous désirez apprendre le langage Python, mais ne savez pas trop par où commencer ? Cette liste de lecture vous permettra de faire vos premiers pas en découvrant l'écosystème de Python et en écrivant de petits scripts.

Au pays des algorithmes

11 article(s) - ajoutée le 01/07/2020
La base de tout programme effectuant une tâche un tant soit peu complexe est un algorithme, une méthode permettant de manipuler des données pour obtenir un résultat attendu. Dans cette liste, vous pourrez découvrir quelques spécimens d'algorithmes.

Analyse de données en Python

10 article(s) - ajoutée le 01/07/2020
À quoi bon se targuer de posséder des pétaoctets de données si l'on est incapable d'analyser ces dernières ? Cette liste vous aidera à "faire parler" vos données.
Plus de listes de lecture