Pourquoi différencier les sections BSS et COMMON?

Aug 29 2020

Je pense que ma question est différente de celle-ci . Ici, je demande pourquoi nous devons différencier ces deux-là, le lien ne répond que celui vers lequel.

Nous savons que:

  • La section commune concerne les variables globales non initialisées et

  • La section Bss concerne les variables statiques non initialisées plus la variable globale initialisée à 0.

Mais pourquoi différencier les sections BSS et COMMON? Surtout pour les variables globales initialisées à 0, ne pouvons-nous pas les mettre dans la section .data qui est pour les variables globales initialisées? N'est-ce pas qu'initialiser une variable à 0 n'est pas aussi une initialisation?

Voici une explication tirée de mon manuel:

dans certains cas, l'éditeur de liens permet à plusieurs modules de définir des symboles globaux avec le même nom. Lorsque le compilateur traduit un module et rencontre un symbole global faible, disons x, il ne sait pas si d'autres modules définissent également x, et si c'est le cas, il ne peut pas prédire laquelle des multiples instances de x le lieur pourrait choisir. Ainsi, le compilateur reporte la décision à l'éditeur de liens en attribuant x à COMMON. D'un autre côté, si x est initialisé à zéro, alors c'est un symbole fort, donc le compilateur peut l'assigner en toute confiance à bss.

Je suis vraiment confus, il dit "on ne sait pas si d'autres modules définissent aussi x", mais comment définir deux fois une variable? Un exemple de code est-il disponible pour illustrer?

Réponses

3 yugr Aug 29 2020 at 07:15

.bss section est utilisée pour allouer des données initialisées à zéro à des fins d'optimisation, pour permettre

  • éditeur de liens statique pour réduire la taille de l'exécutable (mais ne pas y stocker de zéros)
  • runtime linker (loader) pour accélérer le processus de chargement: les données communes sont efficacement initialisées soit en mappant une page physique dédiée remplie de zéros, soit en memsetinsérant de la mémoire au démarrage.

La section commune est utilisée (sur certaines plates-formes, par exemple Windows mais pas ELF) pour implémenter ce que l'on appelle des "symboles communs", c'est-à-dire des symboles qui peuvent être dupliqués dans différents fichiers objets ("unités de traduction"). Quand un tel symbole tombe dans une section commune, l'éditeur de liens statique fusionnera toutes les définitions séparées (avec certaines règles spécifiques à la plate-forme, par exemple fusionner uniquement si elles sont identiques, préfèrent la plus grande définition, etc.).

Sur certaines cibles, les sections communes ne sont utilisées que pour les données non initialisées (ce qui les rend quelque peu similaires à .bss) et sur d'autres également pour les symboles vagues . En général, il n'y a pas de raisons logiques pour lesquelles différentes plates-formes ont fait des choix différents concernant l'utilisation des sections communes, c'est purement historique.

Vous pouvez trouver un historique des symboles communs dans [l'article de Raymond Chen] (https://devblogs.microsoft.com/oldnewthing/20161024-00/?p=94575).