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. #21
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par gorgonite
    j'y ai pensé... mais je n'ai pas réussi à comprendre l'erreur
    L'erreur est celle que j'indique. Avec ce que tu donnes ici, tu copies ce qu'il y a entre .L2 et .L3 qui ne contient pas d'instructions de saut ni de return a la fin. Donc tu executes n'importe quoi.

    (Note que les problemes se combinent peut-etre avec l'impossibilite d'executer le code dans le tas, plutot que d'allouer avec malloc, essaye de mmap avec les flags qui autorisent l'execution).

    On commence a sortir pas mal du cadre du C. C'est quoi un forum adequat?

  2. #22
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par gorgonite
    à 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)
    La page que j'ai donnee a une section historique qui attribue a C. Moore l'invention du threaded code avec ce meme papier de Bell comme premiere publication.

  3. #23
    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 : 41
    Localisation : France

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

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet
    On commence a sortir pas mal du cadre du C. C'est quoi un forum adequat?

    le forum adequat... ben j'en vois pas
    j'ose pas aller poster sur le forum assembleur, je ne code rien en assembleur
    Evitez les MP pour les questions techniques... il y a des forums
    Contributions sur DVP : Mes Tutos | Mon Blog

  4. #24
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    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
    int blockExecute() {
        int fd = open("/dev/zero", O_RDWR);
        if (fd == -1) {
            perror("open");
            exit(EXIT_FAILURE);
        }
        size_t size = 2*(&&block_end - &&block_begin)
            + &&block2_end-&&block2_end;    
        unsigned char* buf = mmap(NULL, size, PROT_EXEC|PROT_READ|PROT_WRITE,
                                  MAP_PRIVATE, fd, 0);
        if (buf == MAP_FAILED) {
            perror("mmap");
            exit(EXIT_FAILURE);
        }
        unsigned char* block = buf;
        unsigned char* done = &&block2_end;
        memcpy(buf, &&block_begin, &&block_end - &&block_begin);
        buf += &&block_end - &&block_begin;        
        memcpy(buf, &&block_begin, &&block_end - &&block_begin);
        buf += &&block_end - &&block_begin;        
        memcpy(buf, &&block2_begin, &&block2_end - &&block2_begin);
        int i = 2;
        goto *block;
     
    block_begin: {
    	i *= 3;
    }
    block_end:
     block2_begin: {
        goto *done;
    }
        block2_end:;
        return i;
     
    }
    a l'air de fonctionner ici.

  5. #25
    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 : 41
    Localisation : France

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

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet
    ... a l'air de fonctionner ici.

    merci pour le bout de code, j'étais encore en train de débugger le mien

    en revanche, sur ma machine, le programme ne plante pas... mais ne s'arrête pas non plus
    Evitez les MP pour les questions techniques... il y a des forums
    Contributions sur DVP : Mes Tutos | Mon Blog

  6. #26
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par gorgonite
    en revanche, sur ma machine, le programme ne plante pas... mais ne s'arrête pas non plus
    x86 linux, ca marche Sparc solaris ca marche.
    Power AIX, ca plante. Mais mes connaissance en assembleur Power sont insuffisantes pour comprendre le probleme et j'ai pas le temps d'y plonger.

  7. #27
    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 : 41
    Localisation : France

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

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet
    x86 linux, ca marche Sparc solaris ca marche.
    Power AIX, ca plante. Mais mes connaissance en assembleur Power sont insuffisantes pour comprendre le probleme et j'ai pas le temps d'y plonger.

    bizarre je suis en x86 linux
    Evitez les MP pour les questions techniques... il y a des forums
    Contributions sur DVP : Mes Tutos | Mon Blog

  8. #28
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par gorgonite
    bizarre je suis en x86 linux
    gdb, CTRL-C et desassembler ce qu'il y a autour.

  9. #29
    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 : 41
    Localisation : France

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

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Par défaut
    tout marche jusqu'au goto *block;

    puis ça ne veut plus

    Error accessing memory address 0x0: Input/output error.
    mais j'arrive pas à déterminer plus précisement où ça plante


    pour infos, j'ai gcc 4.1.2 sous Ubuntu
    Evitez les MP pour les questions techniques... il y a des forums
    Contributions sur DVP : Mes Tutos | Mon Blog

  10. #30
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 615
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 615
    Billets dans le blog
    2
    Par défaut
    mmmmm la variable buf stockant une adresse fournie par mmap, ce serait pas mieux qu'elle soit en globale ??

    là ton diagnostic sort *block est NULL, or block correspond à buf, qui correspond à mmap...


    Enfin, c'que j'en dit.... Z'êtes trop sioux pour moi ...

  11. #31
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par gorgonite
    gcc 4.1.2
    C'est l'explication. Amusant, si tu compiles en optimise, ca "fonctionne" mais ca donne un resultat incorrect.

    C'est bien ce que je disais ci-dessus, la methode depend de trop de suppositions sur la maniere dont est genere le code, et ce meme sans optimisation avec gcc...

  12. #32
    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 : 41
    Localisation : France

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

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Par défaut
    exact... ça marche

    il ne me reste plus qu'à trouver une autre méthode
    Evitez les MP pour les questions techniques... il y a des forums
    Contributions sur DVP : Mes Tutos | Mon Blog

  13. #33
    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 : 41
    Localisation : France

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

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Par défaut
    Salut,


    au fait, il y avait block2_end - block2_end au lieu de block2_end - block2_begin


    par ailleurs, le résultat renvoyée est 6... et non 12 (j'avais pas fait gaffe sur le coup )


    enfin, si je rajoute un autre bloc, suivant ce que j'y mets, mmap envoie un message d'erreur différent

    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
    int testBlockExecute() {
        int fd = open("/dev/zero", O_RDWR);
        if (fd == -1) {
            perror("open");
            exit(EXIT_FAILURE);
        }
        size_t size = (&&block_end - &&block_begin) + (&&blockBis_end - &&blockBis_begin) + (&&block2_end-&&block2_begin);
        unsigned char* buf = mmap(NULL, size, PROT_EXEC|PROT_READ|PROT_WRITE,
                                  MAP_PRIVATE, fd, 0);
        if (buf == MAP_FAILED) {
            perror("mmap");
            exit(EXIT_FAILURE);
        }
        unsigned char* block = buf;
        unsigned char* done = &&block2_end;
        memcpy(buf, &&block_begin, &&block_end - &&block_begin);
        buf += &&block_end - &&block_begin;    
        memcpy(buf, &&blockBis_begin, &&blockBis_end - &&blockBis_begin);
        buf += &&blockBis_end - &&blockBis_begin;        
        memcpy(buf, &&block2_begin, &&block2_end - &&block2_begin);
        int j, i=2;
        goto *block;
     
    block_begin: 
    	i = 3;
    block_end:
    blockBis_begin:
    	i = 5;
    blockBis_end:
    block2_begin: {
        goto *done;
    }
    block2_end:
        return i; 
    }
    contenu de blockBis
    • i = 5; => mmap: Cannot allocate memory
    • j = 5; => mmap: Invalid argument



    y aurait-il un autre allocateur entre le malloc, calloc & cie et le mmap ?
    Evitez les MP pour les questions techniques... il y a des forums
    Contributions sur DVP : Mes Tutos | Mon Blog

  14. #34
    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 : 41
    Localisation : France

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

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Par défaut
    au passage, j'ai tenté de ne pas passer par mmap, mais plutôt par malloc puis mprotect... afin d'éviter les erreurs bizarres de mmap

    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
    int testBlockExecute() {
        size_t size = (&&block_end - &&block_begin)  + (&&block2_end-&&block2_begin);
        unsigned char* buf = malloc(size);
        mprotect(buf,size,PROT_EXEC|PROT_READ|PROT_WRITE);
     
        unsigned char* block = buf;     
        memcpy(buf, &&block2_begin, &&block2_end - &&block2_begin);
     
        int i=2;
        unsigned char* done = &&block2_end;
        goto *block;
     
    block_begin: 
    	i *= 3;
    block_end:
    block2_begin: {
        goto *done;
    }
    block2_end:
        return i; 
    }
    mais, ça plante autant à l'exécution

    Trappe pour point d'arrêt et de trace (core dumped)

    si quelqu'un a une solution, ou même une piste... ça m'arrangerait beaucoup
    Evitez les MP pour les questions techniques... il y a des forums
    Contributions sur DVP : Mes Tutos | Mon Blog

  15. #35
    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 : 41
    Localisation : France

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

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Par défaut
    j'ai trouvé un commencement d'explication sur mon problème...

    http://lists.apple.com/archives/Darw.../msg00021.html


    malheureusement msync() ne change rien à la situation, et cacheflush ne semble pas disponible sous ma distribution (Ubuntu Feisty 7.0.4)


    si quelqu'un voit comment refaire cette fonction sur une architecture x86, ça m'intéresse
    Evitez les MP pour les questions techniques... il y a des forums
    Contributions sur DVP : Mes Tutos | Mon Blog

  16. #36
    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 : 41
    Localisation : France

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

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Par défaut
    au passage, mon code actuel est le suivant :

    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
    48
     
    int testBlockExecute() {
        size_t size = (&&block_end - &&block_begin)  + (&&block2_end-&&block2_begin);
    #ifndef NOT_MMAP
        unsigned char* buf = mmap(NULL, size, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
        if (buf == MAP_FAILED) {
            perror("mmap");
            exit(EXIT_FAILURE);
        }
    #else
    	unsigned char* buf = malloc(size);
    	if (buf == NULL) {
    		perror("malloc");
    		exit(EXIT_FAILURE);
    	}
    	if (mprotect(buf,size,PROT_EXEC|PROT_READ|PROT_WRITE) != 0) {
    		perror("mprotect");
    		exit(EXIT_FAILURE);
    	}
    #endif
     
        unsigned char* block = buf;
        memcpy(buf, &&block2_begin, &&block2_end - &&block2_begin);
     
    	if (msync(block,size,MS_INVALIDATE) != 0) {
    		perror("msync");
    		exit(EXIT_FAILURE);
    	}
    /*	if (cacheflush(block,size,BCACHE) != 0) {
    		perror("cacheflush");
    		exit(EXIT_FAILURE);
    	}*/
        int i=2;
        unsigned char* done = &&block2_end;
        fprintf(stderr,"début de l'exécution\n");
        FUNCTYPE fn = (FUNCTYPE) block;
        fn();
        goto *done;
     
    block_begin: 
    	i *= 3;
    block_end:
    block2_begin: {
        goto *done;
    }
    block2_end:
        return i; 
    }
    Evitez les MP pour les questions techniques... il y a des forums
    Contributions sur DVP : Mes Tutos | Mon Blog

  17. #37
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Je crains que ton approche soit vouee a etre fragile et a dependre fortement du systeme et du compilateur. En changer ou changer les options risque de tout casser.

  18. #38
    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 : 41
    Localisation : France

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

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet
    Je crains que ton approche soit vouee a etre fragile et a dependre fortement du systeme et du compilateur. En changer ou changer les options risque de tout casser.

    j'ai bien compris... mais je n'en ai pas encore trouver d'autres (si ce n'est faire ce morceau direct en asm pour être sûr que le compilo ne le casse pas )
    Evitez les MP pour les questions techniques... il y a des forums
    Contributions sur DVP : Mes Tutos | Mon Blog

  19. #39
    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 : 41
    Localisation : France

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

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Par défaut
    pour infos, en -O0 ceci fonctionne...

    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
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    #include <sys/mman.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
     
    int testBlockExecute() {
       size_t size;
       unsigned char *buf;
       unsigned char *block;
       int i = 2;
       unsigned char *done;
     
       int (*pputs)(const char*)=&puts;
       done = &&end;
       size = (&&block_end - &&block_begin)  + (&&block2_end - &&block2_begin);
       size += (&&blockBis_end - &&blockBis_begin);
       fprintf(stderr,"size buf\t%d\n",size);
     
       buf = mmap(NULL, size, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE|0x20, -1, 0);
       if (buf == MAP_FAILED) {
          perror("mmap");
          exit(EXIT_FAILURE);
       }
     
       block = buf;
     
       memcpy(buf, &&block_begin, &&block_end - &&block_begin);
       buf += &&block_end - &&block_begin;
       memcpy(buf, &&blockBis_begin, &&blockBis_end - &&blockBis_begin);
       buf += &&blockBis_end - &&blockBis_begin;
       memcpy(buf, &&block2_begin, &&block2_end - &&block2_begin);
       buf += &&block2_end - &&block2_begin;
     
       if (msync(block, size, MS_INVALIDATE) != 0) {
          perror("msync");
          exit(EXIT_FAILURE);
       }
     
       fprintf(stderr,"début de l'exécution\n");
       goto *block;
       fprintf(stderr,"ce morceau n'est pas atteignable\n");
     
     
    blockBis_begin:
       i /= 5;
    blockBis_end:
     
    block_begin:
       pputs("addition");
       i *= 3;
    block_end:
     
     
     
    block2_begin: {
       __asm__ volatile ("jmp *%0" : : "m" (done));
    }
    block2_end:
     
    end:
     
       return i;
     
    }
     
    int main (void) {
       int i;
     
       i = testBlockExecute();
       printf("%d\n", i);
     
       return EXIT_SUCCESS;
    }
    si vous passez à -01 ou -0s, le pputs fait un segfault, et de toute façon, sans lui, ça renvoie 0 au lieu de 1 (comme si les instructions n'étaient plus exécutées dans le même ordre )
    Evitez les MP pour les questions techniques... il y a des forums
    Contributions sur DVP : Mes Tutos | Mon Blog

  20. #40
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Je remets une couche et apres j'arrete, c'est promis.

    Pour fonctionner correctement, ce genre de code fait beaucoup d'hypotheses sur la maniere dont le compilateur genere du code. Ces hypotheses peuvent sembler raisonnables, mais le fait qu'il y a des problemes meme avec gcc -O0 montre qu'il n'en est rien.

    Ca va avoir l'air de fonctionner et casser apres un changement anodin qui fera que la generation de code sera legerement differente.

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 3 PremièrePremière 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