Pourquoi tous les codes compilés ne sont-ils pas indépendants des positions?

StackOverflow https://stackoverflow.com/questions/813980

  •  03-07-2019
  •  | 
  •  

Question

Lors de la compilation de bibliothèques partagées dans gcc, l'option -fPIC compile le code en tant qu'indépendant de la position. Existe-t-il une raison (performance ou autre) pour laquelle vous ne compileriez pas tout code indépendant de la position du code?

Était-ce utile?

La solution

Cela ajoute une indirection. Avec un code indépendant de la position, vous devez charger l’adresse de votre fonction puis y accéder. Normalement, l’adresse de la fonction est déjà présente dans le flux d’instructions.

Autres conseils

Oui, il y a des raisons de performance. Certains accès sont effectivement sous une autre couche d'indirection pour obtenir la position absolue en mémoire.

Il existe également le GOT (Global Offset Table) qui stocke les décalages de variables globales. Pour moi, cela ressemble à une table de correction IAT, qui est classée en fonction de la position par wikipedia et quelques autres sources.

http://en.wikipedia.org/wiki/Position_independent

Cet article explique le fonctionnement du PIC et le compare à l’alternative - déplacement au moment du chargement . Je pense que cela correspond à votre question.

En plus de la réponse acceptée. Une des choses qui nuit le plus aux performances du code PIC est l’absence "d’adressage relatif IP". sur x86. Avec "adresse relative IP" vous pouvez demander des données représentant X octets à partir du pointeur d'instruction en cours. Cela simplifierait beaucoup le code PIC.

Les sauts et les appels sont généralement relatifs à EIP, ils ne posent donc pas vraiment de problème. Cependant, accéder aux données demandera un peu plus de tricherie. Parfois, un registre sera temporairement réservé en tant que "pointeur de base". aux données requises par le code. Par exemple, une technique courante consiste à abuser du fonctionnement des appels sur x86:

call label_1
.dd 0xdeadbeef
.dd 0xfeedf00d
.dd 0x11223344
label_1:
pop ebp            ; now ebp holds the address of the first dataword
                   ; this works because the call pushes the **next**
                   ; instructions address
                   ; real code follows
mov eax, [ebp + 4] ; for example i'm accessing the '0xfeedf00d' in a PIC way

Cette technique, parmi d’autres, ajoute une couche d’indirection aux accès aux données. Par exemple, le GOT (Global offset table) utilisé par les compilateurs gcc.

x86-64 a ajouté un "relatif RIP" mode qui rend les choses beaucoup plus simples.

Parce que la mise en œuvre de code totalement indépendant de la position ajoute une contrainte au générateur de code, ce qui peut empêcher l'utilisation d'opérations plus rapides, ou ajouter des étapes supplémentaires pour préserver cette contrainte.

Cela pourrait être un compromis acceptable pour obtenir un multitraitement sans système de mémoire virtuelle, dans lequel vous faites confiance aux processus pour ne pas envahir la mémoire de l'autre et nécessiter le chargement d'une application particulière à n'importe quelle adresse de base.

Dans de nombreux systèmes modernes, les compromis en termes de performances sont différents et un chargeur de repositionnement est souvent moins coûteux (il coûte chaque fois que le code est chargé en premier) que ce que l'optimiseur peut faire de mieux s'il est libre. De plus, la disponibilité d'espaces d'adresses virtuels masque en grande partie la motivation pour l'indépendance de la position.

De plus, le matériel de mémoire virtuelle de la plupart des processeurs modernes (utilisé par la plupart des systèmes d’exploitation modernes) signifie que beaucoup de code (toutes les applications de l’espace utilisateur, à l’exception de l’usage insolite de mmap ou autre) n’a pas besoin d’être indépendant de la position. Chaque programme obtient son propre espace d'adressage qui, pense-t-il, commence à zéro.

Le

code indépendant de la position a une surcharge de performances sur la plupart des architectures, car il nécessite un registre supplémentaire.

Donc, ceci est dans un but de performance.

De nos jours, le système d’exploitation et le compilateur font de tout le code indépendant de la position. Essayez de compiler sans l'indicateur -fPIC, le code se compilera bien mais vous obtiendrez juste un avertissement. Comme pour Windows, une technique appelée mappage de la mémoire est utilisée pour y parvenir.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top