0
votes

Comment le segment de texte est-il fait en lecture seule?

Je sais que le segment de texte est un segment en lecture seule et d'essayer d'écrire des résultats dans la "erreur de bus". Je suis curieux de savoir comment ce segment est fait en lecture seule.

Étant donné que la mémoire physique n'est pas réadonnée, cela doit être fait pendant la pagination.

Y a-t-il un peu pour chaque page de la mémoire pour les pages en lecture seule définies pour le segment de texte?


4 commentaires

Dépend de l'architecture. Où avez-vous vu une erreur de bus?


Il y a des drapeaux d'autorisation dans les entrées de la table de page.


Le chargeur d'exécution est responsable de la configuration des mappages d'adresse, y compris une protection différente de chaque segment chargé. Le système d'exploitation est responsable de l'application des protections au niveau de la page. Une vue très résumée.


Le système de protection de la mémoire est conscient de quelles pages un processus peut lire et à quelles pages un processus peut écrire. Le noyau est notifié lorsqu'une violation survient (ce qui pourrait le faire échanger dans une page, par exemple, ou envoyer un signal SIGSEGV). Lisez sur la mémoire de la mémoire / la mémoire virtuelle.


3 Réponses :


2
votes

Généralement, une manière dont cela se produit est que le chargeur de programme alloue la mémoire du texte du programme, lit le texte du programme dans le fichier exécutable et demande au système d'exploitation de faire en sorte que la mémoire est en lecture seule. Le système d'exploitation enregistre celui-ci dans ses bases de données et transmet les informations au matériel pour le dire de ne pas autoriser à écrire à cette mémoire.

Une autre possibilité est que le chargeur ne lit pas réellement le texte du programme dans la mémoire, mais également émettre une demande au système d'exploitation pour marquer que la partie appropriée du fichier exécutable est "mappée" en mémoire uniquement. Lorsque le processus essaie réellement d'exécuter le code dans une page de mémoire, le système d'exploitation le lira en mémoire (avec accès en écriture pour elle-même, il peut donc le faire) et la marquer en lecture seule (pour le processus).

Ce dernier cas est une optimisation car elle permet à votre programme de commencer sans charger tout cela en premier. Et certaines parties qui ne sont jamais utilisées, telles que le code pour gérer des erreurs rares, ne peuvent jamais être chargées.


1 commentaires

@Sandy: Différents matériels ont différentes façons de gérer cela. Il existe généralement des entrées de table de page de divers formats qui indiquent au matériel que certaines adresses de mémoire virtuelles sont mappées sur une adresse de mémoire physique avec certaines autorisations, et parfois avec des informations sur les processus. Les entrées de la table peuvent être transmises au matériel en les plaçant dans des emplacements spéciaux de mémoire ou des registres spéciaux ou en utilisant des instructions spéciales, en fonction du matériel.



3
votes

Un fichier ELF (un exécutable UNIX ou un objet partagé) dispose de deux concepts principaux:

section: forte> une zone à l'intérieur du fichier exécutable avec un rôle spécifique. Il peut y avoir différentes sections à l'intérieur d'un fichier elfe (peut être visible dans Man elfe ). Les sections communes dans un fichier ELF sont les suivantes: p>

  • .text code> (sht_progbits): le code exécutable réel dans le fichier ELF. LI>
  • .dynsym code> (sht_dynsym): contient des informations sur les symboles qui doivent être récupérés de manière dynamique. LI>
  • .Rela.dynn code> et .Rela.plt code> (sht_rela): Maintenez les informations de relocalisation de la liaison dynamique à utiliser lors du chargement du fichier ELF en mémoire. LI >
  • .Dynamic code> (sht_dynamic): contient des informations sur la liaison dynamique, telles que d'autres dépendances, des compensations pour différentes sections dans le temps d'exécution, etc. Li>
  • .symtab code> (sht_symtab): contient une table de symboles. Li>
  • .Strtab code> (sht_strtab): contient une table à cordes. LI> ul>

    Il y a plus de sections et ce qui précède ne sont que quelques-uns des quelques-uns communs. p>

    Utilisation lookelf code> On peut voir toutes les sections d'un fichier ELF: p> xxx pré>

    exécutant cette commande sur un objet partagé dans mon ordinateur donne la sortie suivante (simplifiée): p> xxx pré>

    Segment: strong> une zone à l'intérieur de l'exécutable avec des instructions de charge pour la liaison dynamique. Signification, un segment n'est qu'une zone à l'intérieur du fichier ELF qui doit être chargée dans une mémoire d'adresse préférée et disposer d'autorisations spécifiques, d'alignement, etc. p>

    chaque section (qui est une zone dans le fichier ELF avec Un rôle logique) devrait faire partie d'un segment, avec les autorisations et les caractéristiques correctes. Un segment peut avoir plus d'une seule section à l'intérieur, et une section est à l'intérieur d'un seul segment (une relation unique). P>

    Utilisation de lookelf code> On peut voir tous les segments de Un fichier elfe: p> xxx pré>

    exécutant cette commande sur un objet partagé dans mon ordinateur entraîne la sortie suivante: P>

    There are 7 program headers, starting at offset 64
    
    Program Headers:
      Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
      LOAD           0x000000 0x0000000000000000 0x0000000000000000 0x00079c 0x00079c R E 0x200000
      LOAD           0x000e00 0x0000000000200e00 0x0000000000200e00 0x000230 0x000238 RW  0x200000
      DYNAMIC        0x000e18 0x0000000000200e18 0x0000000000200e18 0x0001c0 0x0001c0 RW  0x8
      NOTE           0x0001c8 0x00000000000001c8 0x00000000000001c8 0x000024 0x000024 R   0x4
      GNU_EH_FRAME   0x000718 0x0000000000000718 0x0000000000000718 0x00001c 0x00001c R   0x4
      GNU_STACK      0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW  0x10
      GNU_RELRO      0x000e00 0x0000000000200e00 0x0000000000200e00 0x000200 0x000200 R   0x1
    
     Section to Segment mapping:
      Segment Sections...
       00     .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .plt.got .text .fini .rodata .eh_frame_hdr .eh_frame 
       01     .init_array .fini_array .jcr .dynamic .got .got.plt .data .bss 
       02     .dynamic 
       03     .note.gnu.build-id 
       04     .eh_frame_hdr 
       05     
       06     .init_array .fini_array .jcr .dynamic .got 
    


2 commentaires

J'ai un fichier d'objet avec 25 sections, mais zéro segments. Comment est-ce possible?


Pouvez-vous partager la sortie de lookelgments ?



0
votes

Ce n'est pas obligé d'être. Vous pouvez faire le segment de texte d'un programme lire écrire. Mais vous devez instruire à ce sujet à ce sujet. Le système d'exploitation génère des pages générant une faute de page lorsque vous essayez d'écrire sur eux, mais pas lorsque vous essayez de lire. Cela fait partie du système de protection multi-utilisateurs (également appelé système de protection de la mémoire).

La raison du segment de texte en cours de lecture n'est qu'un héritage de l'époque antique. Les multiples instances d'un seul programme appelé par différents processus (par exemple, différents utilisateurs faisant un ls pour afficher leur propre contenu de répertoire) Utilisez le même segment que le texte, alors pourquoi ne pas partager ce segment et éviter Pour le charger à chaque instance pour chaque instance? C'est la raison, mais si vous souhaitez modifier le segment de texte de votre programme au moment de l'exécution, vous pouvez la désigner comme une vache (O) OPY (O) N (W) Rite ) Et les pages seront copiées individuellement lorsque vous essayez d'écrire sur eux, vous avez donc la douceur qu'il est lu / écrire.


0 commentaires