IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

exécution de "blocs" d'instruction créés dynamiquement


Sujet :

C

  1. #1
    Rédacteur/Modérateur

    Avatar de gorgonite
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Décembre 2005
    Messages
    10 322
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Points : 18 679
    Points
    18 679
    Par défaut exécution de "blocs" d'instruction créés dynamiquement
    Salut,


    J'ai un léger problème pour réussir à exécuter des blocks d'instructions que j'ai créé dynamiquement

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    void blockExecute() {
    	size_t size = &&block_end - &&block_begin;
    	void* buf = malloc(size);
    	if (buf == NULL) {
    		puts("allocation du buffer impossible");
    		fflush(stdout);
    		exit(-1);
    	}
    	void* block = memcpy(buf, &&block_begin, size);
     
    	puts("début de l'exécution");
    	fflush(stdout);
    	goto *block;
     
    block_begin:
    	puts("coucou");
    block_end: return;
     
    }
     
    int main(int argc, char** argv) {
    	blockExecute();
    	return 0;
    }

    et ça me sort ceci :
    gorgonite@GorgonMobile$ make BasicBlocks.exe
    gcc -O0 -Wall BasicBlocks.c -o BasicBlocks.exe
    gorgonite@GorgonMobile$ ./BasicBlocks.exe
    début de l'exécution
    Erreur de segmentation (core dumped)

    si quelqu'un voit comment s'y prendre... ça m'intéresserait
    Evitez les MP pour les questions techniques... il y a des forums
    Contributions sur DVP : Mes Tutos | Mon Blog

  2. #2
    Membre émérite
    Avatar de TheGzD
    Homme Profil pro
    Ingénieur/ Docteur en Informatique
    Inscrit en
    Avril 2007
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Ingénieur/ Docteur en Informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 327
    Points : 2 677
    Points
    2 677
    Par défaut
    Je te conseille de rajouter quelques printf histoire de vérifier si les adresses que tu souhaites utiliser et donc la taille de mémoire que tu souhaites allouer sont corrects.
    De plus je me demande si tu ne devrais pas faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void* buf = malloc(size+1); // au lieu de size seuleument
    Bon courage
    Vous postez du code ? Merci d'utiliser les balises
    Un message vous paraît pertinent ? Merci de le gratifier d'un vote positif
    Vous avez obtenu une réponse à votre question ? Merci d'utiliser le tag
    __________________
    Ingénieur R&D, diplômé en 2007 de l'ISIMA
    Docteur en informatique, diplômé en 2015 de l'EDSPI de Clermont-Ferrand

  3. #3
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Points : 9 818
    Points
    9 818
    Par défaut
    Je crois que c'est dû au fait que les pages mémoires ont des droits spécifiques. Par exemple, tu ne peux exécuter que les pages qui ont le droit d'exécution (le segment CODE). Là, tu essayes d'exécuter dans le tas, et on a pas le droit.
    Ceci dépend des systèmes.


    De plus, le retour ne doit pas très bien se faire. Tu fais puts, et après, ça part en vrille car il n'y a pas de retour. Tu as essayé d'utiliser GDB pour voir d'où venait l'erreur exactement ?
    Je ne répondrai à aucune question technique en privé

  4. #4
    Rédacteur/Modérateur

    Avatar de gorgonite
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Décembre 2005
    Messages
    10 322
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Points : 18 679
    Points
    18 679
    Par défaut
    Citation Envoyé par millie
    Je crois que c'est dû au fait que les pages mémoires ont des droits spécifiques. Par exemple, tu ne peux exécuter que les pages qui ont le droit d'exécution (le segment CODE). Là, tu essayes d'exécuter dans le tas, et on a pas le droit.
    Ceci dépend des systèmes.

    justement sur les x86, cette sécurité n'est pas implantée.... car le controle en exécution des pages mémoire ne se fait pas au même niveau que sur les autres architectures ; c'est entre autre pour cela que les shell code sont redoutables
    (enfin, si j'ai bien compris )


    Citation Envoyé par millie
    De plus, le retour ne doit pas très bien se faire. Tu fais puts, et après, ça part en vrille car il n'y a pas de retour. Tu as essayé d'utiliser GDB pour voir d'où venait l'erreur exactement ?
    ben je mets le retour...


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    void blockExecute() {
    	size_t size = &&block_end - &&block_begin;
    	void* buf = malloc(size+1);
    	if (buf == NULL) {
    		puts("allocation du buffer impossible");
    		fflush(stdout);
    		exit(-1);
    	}
    	void* block = memcpy(buf, &&block_begin, size);
    	printf("adresse du bloc %p\tlongueur %d\n",&&block_begin,(int) size);
    	printf("adresse du buffer %p\n",block);
     
    	puts("début de l'exécution");
    	fflush(stdout);
    	goto *block;
     
    block_begin:
    	puts("coucou");
    	return;
    block_end: return;
     
    }

    au passage, j'ai fait les printf conseillés par TheGzD

    gorgonite@GorgonMobile$ ./BasicBlocks.exe
    adresse du bloc 0x804855c longueur 14
    adresse du buffer 0x804a430
    début de l'exécution
    Erreur de segmentation (core dumped)
    Evitez les MP pour les questions techniques... il y a des forums
    Contributions sur DVP : Mes Tutos | Mon Blog

  5. #5
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Points : 9 818
    Points
    9 818
    Par défaut
    J'ai un peu plus regardé, histoire de voir si les bonnes zones étaient bien copiées.

    J'ai également fait tourner le programme sur un SPARC, j'ai également l'erreur de segmentation. Je pense qu'il y a tout de même une protection sur l'exécution de page virtuelle qui se trouve dans le tas, même sous x86.


    Voilà le dernier code modifié :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    #include <stdio.h>
    #include <stdlib.h>
    #include <signal.h>
     
    void handler(int i)
    {
     fprintf(stderr, "Oula, je n'ai pas segfaulté\n");
    }
     
    void blockExecute()
    {
      ssize_t size = &&block_end - &&block_begin;
      fprintf(stderr, "Size : %d\n", (int) size);
      void* buf = malloc(size);
      if (buf == NULL)
      {
        puts("allocation du buffer impossible");
        fflush(stdout);
        exit(-1);
      }
     
     
      void* block = memcpy(buf, &&block_begin, size);
     
      char * chaine = block;
      char * chaineA = &&block_begin;
      fprintf(stderr," Chaine   : %10s\n", chaine);
      fprintf(stderr," Chaine A : %10s\n", chaineA);
      void * blockNormal = &&block_begin;
     
      fprintf(stderr, "début de l'exécution");
      goto *buf;
     
      return;
    block_begin:
      fprintf(stderr, "Ici");
      goto block_end;
    block_end:
     return;
    }
     
    int main(void)
    {
      signal(SIGSEGV, handler);
      blockExecute();
      return 0;
    }
    Au passage, je te conseille d'utiliser fprintf(stderr, ""); au lieu de printf (stderr n'est pas bufferisé)
    Je ne répondrai à aucune question technique en privé

  6. #6
    Rédacteur/Modérateur

    Avatar de gorgonite
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Décembre 2005
    Messages
    10 322
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Points : 18 679
    Points
    18 679
    Par défaut
    perso, quand je laisse les puts, je me prends une infinité de
    Oula, je n'ai pas segfaulté
    Oula, je n'ai pas segfaulté
    Oula, je n'ai pas segfaulté
    Oula, je n'ai pas segfaulté
    Oula, je n'ai pas segfaulté
    Oula, je n'ai pas segfaulté
    Oula, je n'ai pas segfaulté
    Oula, je n'ai pas segfaulté
    Oula, je n'ai pas segfaulté
    Oula, je n'ai pas segfaulté
    Oula, je n'ai pas segfaulté
    Oula, je n'ai pas segfaulté
    Oula, je n'ai pas segfaulté
    et je retombe sur le même message d'erreur quand je passe tout en fprintf(stderr,...)

    et toi ?
    Evitez les MP pour les questions techniques... il y a des forums
    Contributions sur DVP : Mes Tutos | Mon Blog

  7. #7
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Points : 9 818
    Points
    9 818
    Par défaut
    T'as vu, il n'a pas seg faulté

    Sous linux, j'ai pareil (ce qui est normal, il doit chercher à exécuter, il dit qu'il peut pas, mais il avance, et donc ça boucle comme ça).

    Sous Windows, le programme se finit quand même pas un signal que je n'ai pas déterminé (il affiche tout de même un : Oula je n'ai pas segfaulté avant de finir)

    Sous Solaris/Sparc, j'ai :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Oula, je n'ai pas segfaulté
    Segmentation Fault (core dumped)
    Ce qui est ultra bizarre... A moins qu'il y ait un autre signal qui n'est pas SIGSEGV et qui affiche ça...
    Je ne répondrai à aucune question technique en privé

  8. #8
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Meme sans protection, il y a pas mal de chance que le compilateur utilise des sauts relatifs plutot que des sauts absolus comme tu l'esperes, sans parler des effets des optimiseurs.

    Quel est le probleme que tu essaies de resoudre?

    (gnu lightening? je ne sais pas dans quel etat c'est)
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  9. #9
    Rédacteur/Modérateur

    Avatar de gorgonite
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Décembre 2005
    Messages
    10 322
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Points : 18 679
    Points
    18 679
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet
    Meme sans protection, il y a pas mal de chance que le compilateur utilise des sauts relatifs plutot que des sauts absolus comme tu l'esperes, sans parler des effets des optimiseurs.

    je suis sans optimisation pour le moment -O0

    Citation Envoyé par Jean-Marc.Bourguet
    Quel est le probleme que tu essaies de resoudre?
    je veux pouvoir générer dynamiquement des blocs de code, et les exécuter... c'est tout


    Citation Envoyé par Jean-Marc.Bourguet
    (gnu lightening? je ne sais pas dans quel etat c'est)
    je ne connaissais pas GNU lightening... merci

    mais ça ne s'applique pas à mon problème... on veut absolument se passer de JIT, pour minimiser la consommation mémoire de la vm
    Evitez les MP pour les questions techniques... il y a des forums
    Contributions sur DVP : Mes Tutos | Mon Blog

  10. #10
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par gorgonite
    je suis sans optimisation pour le moment -O0
    Les sauts relatifs doivent quand meme etre la.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    (gdb) x/20i buf
    0x94ef008:      sub    $0x8,%esp
    0x94ef00b:      push   $0x804876f
    0x94ef010:      pushl  0x8049894
    0x94ef016:      call   0x94eedd8
    0x94ef01b:      add    $0x10,%esp
    0x94ef01e:      add    %al,(%eax)
    0x94ef020:      add    %al,(%eax)
    0x94ef022:      add    %al,(%eax)
    0x94ef024:      loope  0x94ef035
    0x94ef026:      add    (%eax),%al
    0x94ef028:      add    %al,(%eax)
    0x94ef02a:      add    %al,(%eax)
    0x94ef02c:      add    %al,(%eax)
    0x94ef02e:      add    %al,(%eax)
    0x94ef030:      add    %al,(%eax)

    je veux pouvoir générer dynamiquement des blocs de code, et les exécuter... c'est tout (enfin je peux donner plus de détails, mais si je réussis mon coup, je pourrais publier un papier pour VEE)
    Tu te fais un tableau de labels sur lequel tu as un pointeur (current), tu commences par
    et tes blocs se terminent par la meme chose.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  11. #11
    Rédacteur
    Avatar de Neitsa
    Homme Profil pro
    Chercheur sécurité informatique
    Inscrit en
    Octobre 2003
    Messages
    1 041
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chercheur sécurité informatique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 041
    Points : 1 956
    Points
    1 956
    Par défaut
    Bonjour,

    le problème est relativement simple, c'est tout simplement parce que un bloc de code relogeable ne doit pas appeler une fonction statique.

    Le code en tant que tel fonctionne très bien (le code entre "block_begin" et "block_end") est bien copié, et on à bien un saut vers la mémoire alloué.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    block_begin:
    	puts("coucou");
    block_end: return;
    Désassemblage du bloc de code dans le programme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    00401370 MOV     DWORD PTR SS:[ESP],Test.0040304B ; ASCII "coucou"
    00401377 CALL    <JMP.puts> ; puts (CALL  0x401A20)
    0040137C ADD     ESP,10 ; nettoyage du stack frame
    0040137F POP     EBX
    00401380 POP     ESI
    00401381 LEAVE ; quitte le stack frame
    00401382 RETN ; retour
    Notez qu'ici, la fonction PUTS est appelée via son import en statique dans le programme. Dans mon cas un CALL 0x401A20

    Le même code dans le tas (heap) alloué par malloc :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    003D3CA8        MOV     DWORD PTR SS:[ESP],40304B    ; ASCII "coucou"
    003D3CAF        CALL    003D4358 ; ne correspond à rien du tout !
    003D3CB4        ADD     ESP,10
    003D3CB7        POP     EBX
    003D3CB8        POP     ESI
    003D3CB9        LEAVE
    003D3CBA        RETN
    Ici le CALL (appelle de fonction / procédure) ne correspond à rien du tout.

    Le CALL sous x86 sont encodé avec un déplacement. Si on prend le CALL vers puts dans le programme (ici avec ses opcodes) :

    Adresse de l'instruction : 0x401377
    Opocde de CALL : 0xE8
    Déplacement (little endian) : 0x06A4

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    00401377 E8 A4060000        CALL    <JMP.puts> ; puts
    Adresse du CALL + déplacement + taille instruction :

    0x401377 + 06A4 + 5 : 0x401A20 (soit l'adresse où est importée la fonction puts)

    Le CALL dans le tas est encodé de la même façon, puisque le memcopy() ne fait que copier les opcodes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    003D3CAF          E8 A4060000          CALL    003D4358
    Seulement ici l'adresse 0x3D4358 ne correspond à rien du tout Donc pour que ce type de code fonctionne il faut aussi recalculer le déplacement nécessaire au CALL...

  12. #12
    Rédacteur/Modérateur

    Avatar de gorgonite
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Décembre 2005
    Messages
    10 322
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Points : 18 679
    Points
    18 679
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet
    Tu te fais un tableau de labels sur lequel tu as un pointeur (current), tu commences par
    et tes blocs se terminent par la meme chose.

    déjà fait... c'est une optimisation classique (de Ricardi si je ne me trompe pas), et je cherche à optimiser un peu plus
    Evitez les MP pour les questions techniques... il y a des forums
    Contributions sur DVP : Mes Tutos | Mon Blog

  13. #13
    Rédacteur/Modérateur

    Avatar de gorgonite
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Décembre 2005
    Messages
    10 322
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Points : 18 679
    Points
    18 679
    Par défaut
    j'ai changé le code de mon bloc pour tester sans appels de méthodes...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    block_begin: {
    //	fprintf(stderr,"coucou\n");
    	int i = 2;
    	i *= 3;
    	return i;
    }
    block_end: return 0;
    et je me prends toujours ceci :

    gorgonite@GorgonMobile$ ./BasicBlocks.exe
    adresse du bloc 0x8048558 longueur 28
    adresse du buffer 0x804a008
    début de l'exécution
    Erreur de segmentation (core dumped)
    Evitez les MP pour les questions techniques... il y a des forums
    Contributions sur DVP : Mes Tutos | Mon Blog

  14. #14
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par gorgonite
    J'ai un léger problème pour réussir à exécuter des blocks d'instructions que j'ai créé dynamiquement
    Il n'y a aucun moyen portable de faire ce que tu veux.
    • Rien ne dit que des étiquettes de goto aient des adresses valides
    • Tu copies du code en mémoire de données. Rien ne dit que cette mémoire ait les droits d'exécution, ni que ces adresses (code) soient valides dans l'espace traité par la copie (données)...

    Bref, le comportement est indéterminé.

    Que veux-tu faire exactement ? Peut être que la méthode n'est pas la bonne...
    Pas de Wi-Fi à la maison : CPL

  15. #15
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par gorgonite
    déjà fait... c'est une optimisation classique (de Ricardi si je ne me trompe pas), et je cherche à optimiser un peu plus
    J'ai tendance a mettre ca en rapport avec les implementations de Forth. Tiens une page sur le sujet http://www.complang.tuwien.ac.at/for...aded-code.html a l'air de l'attribuer (ou des variantes proches) a Charles Moore en 1970. R.K. Dewar a employe des techniques semblables pour SPITBOL.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  16. #16
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Points : 9 818
    Points
    9 818
    Par défaut
    Citation Envoyé par gorgonite
    j'ai changé le code de mon bloc pour tester sans appels de méthodes...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    block_begin: {
    //	fprintf(stderr,"coucou\n");
    	int i = 2;
    	i *= 3;
    	return i;
    }
    block_end: return 0;
    et je me prends toujours ceci :
    Par contre ici, ça ne m'étonne pas. Quand tu déclares int i ici, en fait lors de la compilation, l'espace peut être réservé une fois pour toute dans toute la fonction au niveau de la pile (il y a des implémentations différentes qui ne nécessite pas de pile, mais je parle dans un cas assez "général").

    Ce qui fait que de toute façon, les données seront totalement incohérentes, si par exemple tu appelles ton code crée dynamiquement dans une autre fonction, alors la variable ne sera pas au bon endroit dans la pile (car pas vraiment déclaré)

    De plus, le return i fait pas mal de chose (comme dépiler les arguments, dépiler l'adresse de retour (au moment de l'appel) et revenir dessus. Et il y a de forte chance que ça ne marche pas.
    Je ne répondrai à aucune question technique en privé

  17. #17
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par gorgonite
    j'ai changé le code de mon bloc pour tester sans appels de méthodes...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    block_begin: {
    //	fprintf(stderr,"coucou\n");
    	int i = 2;
    	i *= 3;
    	return i;
    }
    block_end: return 0;
    et je me prends toujours ceci :
    Je te suggere de regarder l'assembleur (gcc -S). gcc implemente les return par des sauts a l'epilogue. Et vu que ces sauts sont relatifs, ca ne va jamais marcher par copie.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  18. #18
    Rédacteur/Modérateur

    Avatar de gorgonite
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Décembre 2005
    Messages
    10 322
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Points : 18 679
    Points
    18 679
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Que veux-tu faire exactement ? Peut être que la méthode n'est pas la bonne...

    je veux passer à l'étape de preparation sequences en suivant le modèle décrit dans le papier de Gagnon & Hendren http://www.sable.mcgill.ca/publicati...per-2003-2.pdf

    la création et l'exécution de ses basic blocks est une étape essentielle.

    ils l'ont implanté la sablevm, donc ça doit marcher en x86

    (je ne veux pas recopier le code qu'ils ont, je veux comprendre comment faire cela pour l'appliquer à ma machine virtuelle )
    Evitez les MP pour les questions techniques... il y a des forums
    Contributions sur DVP : Mes Tutos | Mon Blog

  19. #19
    Rédacteur/Modérateur

    Avatar de gorgonite
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Décembre 2005
    Messages
    10 322
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Points : 18 679
    Points
    18 679
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet
    Je te suggere de regarder l'assembleur (gcc -S). gcc implemente les return par des sauts a l'epilogue. Et vu que ces sauts sont relatifs, ca ne va jamais marcher par copie.

    j'y ai pensé... mais je n'ai pas réussi à comprendre l'erreur (mon niveau en asm n'est pas terrible... souvent je génère de l'asm, mais je ne l'écris pas à la main )

    je vais remettre le code


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    int blockExecute() {
    	size_t size = &&block_end - &&block_begin;
    	void* buf = malloc(size+1);
    	void* block = memcpy(buf, &&block_begin, size);
    	int i = 2;
    	goto *block;
     
    block_begin: {
    	i *= 3;
    }
    block_end: return i;
     
    }

    Code asm : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    blockExecute:
            pushl   %ebp
            movl    %esp, %ebp
            pushl   %edi
            pushl   %esi
            subl    $32, %esp
            movl    $.L2, %edx
            movl    $.L3, %eax
            movl    %edx, %ecx
            subl    %eax, %ecx
            movl    %ecx, %eax
            movl    %eax, -24(%ebp)
            movl    -24(%ebp), %eax
            addl    $1, %eax
            movl    %eax, (%esp)
            call    malloc
            movl    %eax, -20(%ebp)
            movl    -20(%ebp), %eax
            movl    -24(%ebp), %edx
            movl    %eax, %edi
            movl    $.L3, %esi
            cld
            movl    %edx, %ecx
            rep
            movsb
            movl    %eax, -16(%ebp)
            movl    $2, -12(%ebp)
            movl    -16(%ebp), %eax
            jmp     *%eax
    .L3:
            movl    -12(%ebp), %eax
            movl    %eax, %edx
            addl    %edx, %edx
            leal    (%edx,%eax), %eax
            movl    %eax, -12(%ebp)
    .L2:
            movl    -12(%ebp), %eax
            addl    $32, %esp
            popl    %esi
            popl    %edi
            popl    %ebp
            ret
            .size   blockExecute, .-blockExecute
            .section        .rodata
    Evitez les MP pour les questions techniques... il y a des forums
    Contributions sur DVP : Mes Tutos | Mon Blog

  20. #20
    Rédacteur/Modérateur

    Avatar de gorgonite
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Décembre 2005
    Messages
    10 322
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Points : 18 679
    Points
    18 679
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet
    J'ai tendance a mettre ca en rapport avec les implementations de Forth. Tiens une page sur le sujet http://www.complang.tuwien.ac.at/for...aded-code.html a l'air de l'attribuer (ou des variantes proches) a Charles Moore en 1970. R.K. Dewar a employe des techniques semblables pour SPITBOL.

    à ma connaissance, le premier papier sur le threaded code date de 1973 (James R. Bell, Communications of the ACM)

    votre exemple date de 1993 (Anton Ertl, A Portable Forth Engine)

    quant à moi, j'en utilise une version différente (qui ajoute aussi quelques inlining)
    papier de 1998 Optimizing direct threaded code by selective inlining par Ricardi et Piumarta

    c'était la première étape de mon travail... elle m'a fait gagner entre 15 et 50% de performances, suivant le type de code qu'on exécute

    je suis désormais dans la deuxième étape de mon travail qui consiste à construire ces basic blocks... pour pouvoir commencer la troisième étape, qui est pour le moment "secrète", et qui devrait me permettre de gagner encore près de 15-20% de perfs en échange d'un peu de mémoire
    Evitez les MP pour les questions techniques... il y a des forums
    Contributions sur DVP : Mes Tutos | Mon Blog

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 3 123 DernièreDernière

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo