FR 2864651 A1 20050701 FR 0315488 A 20031224 La présente invention concerne un procédé pour la simulation d'un environnement d'exécution à l'aide de techniques d'instrumentation de code. Elle permet, en particulier, de simuler, totalement ou partiellement, la sémantique d'exécution d'un environnement d'exécution dit "d'origine" à l'aide d'un environnement dit "de référence". Une telle simulation est particulièrement utile dans les cas où l'environnement de référence offre des facilités dont ne dispose pas l'environnement d'origine comme, par exemple, des facilités d'aide à la mise au point des programmes. On sait qu'il n'est généralement pas question de modifier l'environnement de référence lui-même. Par ailleurs, il n'est pas souhaitable de modifier les programmes pour qu'ils puissent s'exécuter dans l'environnement de référence. Le procédé selon l'invention a donc plus particulièrement pour but de simuler un environnement d'exécution en satisfaisant ces contraintes essentielles et en préservant le comportement des programmes destinés à s'exécuter dans l'environnement d'origine. Il consiste à modifier, de façon automatisée, tout ou partie des programmes écrits pour l'environnement d'origine en y insérant des actions supplémentaires destinées à simuler certains aspects dudit environnement d'origine et à ajouter 2864651 2 à l'environnement de référence des services (bibliothèques de fonctions) proposés par l'environnement d'origine et nécessaires à l'exécution desdits programmes. Avantageusement: É Les susdites actions supplémentaires pourront consister en des appels à des bibliothèques de fonctions ajoutées à l'environnement de référence dans le but de simuler certains aspects de l'environnement d'origine. É La modification automatique des programmes pourra également réaliser un changement du format de ces programmes de manière à les rendre compatibles avec le format d'exécution de l'environnement de référence. É La modification automatique des programmes pourra être effectuée soit avant leur chargement dans l'environnement de référence, soit au moment de leur chargement ou de leur installation dans l'environnement de référence, soit encore au moment de leur exécution. É Certaines actions supplémentaires ou fonctions de bibliothèques pourront réaliser une mise en oeuvre approchée de certaines fonctionnalités de l'environnement d'origine. Ce procédé s'applique notamment, mais non exclusivement, à la simulation d'un environnement défini pour les cartes à puce (par exemple un environnement "Java Card" - marque déposée par la Société Sun Microsystems) - qui jouera alors le rôle d'environnement d'origine, à l'aide d'un environnement "Java", édition standard, (marque déposée par la Société Sun Microsystems) fonctionnant sur des stations de travail ou ordinateurs de bureau et qui sera alors considéré comme l'environnement de référence. Cette application sera utilisée dans la suite de la description pour illustrer le procédé selon l'invention, étant entendu que l'invention ne se limite pas aux deux technologies "Java" précitées ni aux technologies "Java", d'une façon générale. A titre d'exemple, le procédé selon l'invention permet, dans le cas des environnements "Java" et "Java Card", de développer un simulateur de carte à puce, conforme à la technologie "Java Card", s'exécutant dans l'environnement "Java". Il est alors possible d'utiliser toutes les techniques de test et de mise au point disponibles dans l'environnement "Java" pour tester les programmes prévus pour s'exécuter dans l'environnement "Java Card" : débogueur et bibliothèques de fonctions supplémentaires non présentes dans l'environnement "Java Card" par exemple. Le procédé selon l'invention n'est pas lié à un environnement particulier. Il peut s'appliquer en particulier (en plus de toutes les déclinaisons d'environnements "Java" pour stations de travail, cartes à puce, teiiiiinaux, etc.) à l'environnement ".NET" - marque déposée par la Société Microsoft Corporation - qui définit un format binaire exécutable commun à de nombreux langages de programmation. Le procédé selon l'invention pourra s'appliquer avantageusement à des variantes comme les portages de l'environnement.NET sur d'autres types de matériels, notamment sur cartes à puce, téléphones mobiles et matériels de type PDA ("Personal Digital Assistant"). Il pourra également s'appliquer à tous les langages (C# et "Visual Basic" par exemple) qui peuvent être traduits ou compilés pour s'exécuter sur l'environnement.NET. Parmi les types d'application du procédé, on peut notamment citer les cas d'utilisations suivants: 2864651 4 ^ Simulateur sur PC d'un environnement d'exécution spécifique, par exemple, simulateur de carte à puce conforme à la technologie "Java Card", fonctionnant sur PC dans un environnement "Java". ^ Interpréteur de commandes d'un langage de programmation permettant de développer des programmes pour un environnement d'exécution spécifique, en respectant la sémantique d'exécution de ce dernier, par exemple, interpréteur de commandes du langage "Java" fonctionnant sur PC, en adoptant la sémantique d'exécution d'un environnement "Java Card". D'une façon plus précise, le procédé selon l'invention fait appel aux notions suivantes: 1. Compatibilité des environnements d'exécution considérés (d'origine et de référence) : La notion de compatibilité retenue est l'existence pour ces environnements d'un format commun de description de programmes, ce format pouvant être exécuté par l'environnement de référence. Il convient de noter que ce format commun n'est pas nécessairement le format habituel de description des programmes de l'environnement d'origine, la définition retenue permettant notamment la traduction du format de l'environnement d'origine vers le format de l'environnement de référence. A titre d'exemple, dans l'environnement (de référence) "Java", le format binaire exécutable est le format "Class" alors que dans l'environnement (d'origine) "Java Card", ce même format ne représente qu'un format intermédiaire destiné à être transformé en un autre format binaire exécutable, le format "Cap" : dans ce dernier cas néanmoins, le format "Class" contient déjà toute la description du programme. 2864651 -5 Le langage de programmation "Java" permet en effet de décrire des programmes pouvant s'exécuter dans l'environnement "Java" ou "Java Card". Un programme décrit dans ce langage est d'abord transformé à l'aide d'un compilateur en un certain nombre de fichiers "Class". Ces fichiers peuvent être exécutés directement dans l'environnement "Java". Si ce programme est développé spécifiquement pour l'environnement "Java Card", ces fichiers "Class" doivent ensuite être transformés en un fichier "Cap" qui pourra être chargé et exécuté dans l'environnement "Java Card". ("Java Standard") "Java" -i "Class" ("Java Card") "Java" -) "Class" "Cap" Dans le cas des environnements "Java" et "Java Card", le format "Class" représente donc un format commun de description de programmes, de sorte que ces deux environnements sont compatibles et que le procédé peut être appliqué à ces derniers. 2. Instrumentation des programmes prévus pour s'exécuter au sein de l'environnement d'origine. Par programme, on entend ici aussi bien une application autonome que des bibliothèques de fonctions lorsqu'elles sont décrites dans le même format que les programmes et, d'une façon générale, la combinaison de ces différents cas. Cette technique d'instrumentation, que l'on applique au format commun de description de programmes (exécutable par l'environnement de référence), consiste à modifier de façon automatisée tout ou partie des programmes afin d'y insérer des actions supplémentaires. Ces actions consistent typiquement à appeler des services dédiés permettant à l'environnement de référence de simuler l'exécution de l'environnement d'origine. 2864651 6 Les programmes ainsi instrumentés peuvent s'exécuter au sein de l'environnement de référence et néanmoins se comporter de la même façon que s'ils s'exécutaient au sein de l'environnement d'origine. 3. Services dédiés. La définition d'un certain nombre de services dédiés (bibliothèques de fonctions) permettant à l'environnement de référence de simuler l'environnement d'origine. Ces services sont appelés par les programmes lorsqu'ils ont été instrumentés. Les programmes n'ont pas besoin d'être décrits en prenant en compte l'existence de ces services. 4. Bibliothèques de fonctions. On peut ajouter à l'environnement de référence des services contenus dans des bibliothèques de fonctions proposés par l'environnement d'origine et nécessaires aux programmes prévus pour s'exécuter dans ce dernier. Ces bibliothèques peuvent, si nécessaire, être elles-mêmes traitées suivant la technique d'instrumentation précédemment exposée. L'application du procédé selon l'invention peut s'effectuer de différentes manières, selon les critères suivants: ^ L'ensemble des services (bibliothèques de fonctions) de l'environnement d'origine effectivement simulés par l'environnement de référence, le procédé selon l'invention n'imposant pas la fourniture de l'ensemble de ces services par l'environnement de référence. ^ La précision avec laquelle chaque service de l'environnement d'origine est simulé par l'environnement de référence. En effet, certains services de 2864651 7 l'environnement d'origine peuvent ne pas avoir le même sens dans l'environnement de référence, notamment si l'environnement d'origine fonctionne sur un autre type de matériel (cas des services liés à des périphériques, par exemple). Le procédé selon l'invention permet de traiter ce genre de situation en offrant un service approché qui permet aux programmes de poursuivre leur exécution dans l'environnement de référence malgré cette différence d'environnement. ^ Le moment où les programmes sont instrumentés: soit par avance (ou statiquement ) avant leur exécution, soit dynamiquement, lors de leur chargement ou de leur lancement dans l'environnement de référence. ^ Les parties des programmes qui sont effectivement instrumentées à un moment donné, ces parties pouvant être déterminées manuellement par avance, ou automatiquement au moment du chargement ou du lancement de ces programmes. Un mode de mise en oeuvre du procédé selon l'invention, dans le cas des environnements "Java" (environnement de référence) et "Java Card" (environnement d'origine) sera décrit ci-après, à titre d'exemple non limitatif, avec référence aux dessins annexés dans lesquels: La figure 1 est un tableau illustrant le principe de la création d'un objet; La figure 2 est un tableau illustrant le principe de l'instrumentation d'un appel de méthode virtuelle sur une variable locale (argument) ; La figure 3 est un tableau illustrant l'instrumentation d'un appel de méthode virtuelle sur un champ virtuel (c'est-à-dire d'instance). 2864651 -8- On rappelle tout d'abord que l'environnement d'exécution "Java Card", fonctionnant sur carte à puce, permet de charger et d'installer des applets (en français: appliquettes ou petites applications) : ces applets s'enregistrent dans l'environnement avec un identifiant unique, leur AID ("Applet Identifier"). Une telle applet n'est sollicitée que lorsqu'une commande est envoyée, depuis l'extérieur , à la carte à puce, et lui est spécifiquement destinée. Une applet est représentée au sein du système par un objet de type "Applet". Chaque applet définit un contexte et peut créer des objets dont elle est alors l'unique propriétaire: tout objet présent dans l'environnement d'exécution est donc associé, lors de sa création, à un contexte particulier. Lorsqu'une méthode est invoquée sur un objet quelconque de l'environnement, le système mémorise le contexte associé à cet objet, de sorte qu'il existe une notion de contexte couramment actif. Le système garde également en mémoire le contexte précédemment actif, c'est-à-dire, le dernier contexte actif et différent du contexte couramment actif. Ce qui se produit donc lors de l'appel d'une méthode sur un objet est ce que l'on appelle un changement de contexte. L'API "Java Card" permet à une applet, par le biais de la méthode "JC S y s t em. g e tAID", de prendre connaissance du contexte couramment actif en récupérant l'AID de l'applet propriétaire de l'objet courant (celui dont le code est en train de s'exécuter). L'API "Java Card" permet également à une applet, par le biais de la méthode "JCSystem. getPreviousContextAID", de prendre connaissance du contexte précédemment actif. En effet, une applet peut, sous certaines conditions, appeler une méthode sur un objet qui ne lui appartient pas et il peut être intéressant que le code exécutable de l'objet contrôle le contexte couramment ou précédemment actif pour savoir, par exemple, s'il est utilisé par son propriétaire ou une autre applet. 2864651 9 Cette notion de contextes et de changements de contextes n'existe pas dans l'environnement "Java" ("Standard Edition"). Pour exécuter un programme "Java Card" dans l'environnement "Java", il est donc nécessaire de simuler ce mécanisme afin que les méthodes "JCSystem. getAID" et "JCSystem. getPreviousContextAID" retournent des informations valides. Ce mécanisme n'est qu'un exemple des différences existant entre les environnements "Java" et "Java Card". Seule l'application du procédé à cet exemple sera détaillée, étant entendu que le procédé peut être utilisé dans le même esprit pour simuler tout ou partie des mécanismes et/ou règles de contrôle spécifiques à l'environnement "Java Card", notamment l'ensemble de règles constituant le " irewall" (pare-feu logiciel) dans l'environnement "Java Card". Dans cet exemple, le procédé selon l'invention consiste à insérer dans le code exécutable de l'applet, des appels à des fonctions dédiées et indépendantes de l'applet, afin que l'environnement "Java" soit capable de gérer les changements de contextes. On définit d'abord, pour les besoins de l'exemple, une classe "Tracer" contenant les fonctions dédiées à la gestion des changements de contextes dans l'environnement "Java". Il est à noter que le développeur de l'applet n'a jamais connaissance de cette classe. La transformation automatique du code exécutable de cette applet est un procédé qui n'entre en rien dans sa définition. public class Tracer { public static void registerObject(Object o) public static void methodInvoke(Object o) ; public static void methodExit() ; 1 2864651 -10- Il est nécessaire tout d'abord de connaître le propriétaire des objets créés directement ou indirectement par l'applet. Pour cela, on insère dans le code exécutable de l'applet un appel à la méthode "vo i d Tracer. registerObj ect (Obj ect o) " immédiatement après toute demande de création d'objet (précisément, après l'appel au constructeur qui finalise la création de l'objet), avec pour argument l'objet qui vient d'être créé. Ceci permet à la classe "Tracer" de mémoriser le contexte associé à chaque objet, c'est-à-dire le contexte couramment actif, connu de la classe "Tracer", au moment de la création de l'objet. La figure 1 montre un exemple de création d'un objet et la façon dont l'appel à la méthode "Tracer. registerObj ect" peut y être inséré. La notation utilisée pour l'exemple est celle utilisée pour les exemples de la spécification du langage "Java". Ensuite, il est nécessaire de repérer tous les appels de méthodes effectués sur des objets occasionnant des changements de contextes: on ne prend donc pas en compte les appels de méthodes privées, ni les appels de constructeurs d'objets, qui n'occasionnent pas de changements de contextes en "Java Card". On insère alors dans le code exécutable un appel à la méthode statique "void Tracer.methodInvoke (Object o) " immédiatement avant toute demande d'appel de méthode virtuelle sur un objet, avec pour argument l'objet o sur lequel la méthode est appelée. Pour cela, on stocke les arguments de l'appel original (présents sur la pile au moment de l'appel) dans des variables locales (dont le nombre est mis à jour) afin de retrouver l'objet o sur la pile; on duplique alors cet objet pour effectuer l'appel à "Tracer. methodlnvoke", puis on restitue les arguments sur la pile afin d'effectuer l'appel original. Ceci permet finalement à la classe "Tracer" de mettre à jour le contexte actuellement actif, d'après le contexte (connu de la classe "Tracer") associé à l'objet passé en argument. La classe "Tracer" garde en mémoire la liste de tous les contextes précédemment activés afin de 2864651 -11- pouvoir retrouver le contexte qui était actif au moment de l'appel de la méthode virtuelle, lorsque cette méthode se termine. Il est donc également nécessaire d'insérer un appel- à la méthode "v o i d Tracer. met h o dE x i t () immédiatement après les demandes d'appel de méthode virtuelle. Ceci permet à la classe "Tracer" de mettre à jour le contexte courant, en récupérant le contexte qui était actif au moment de l'appel de la méthode virtuelle. La figure 2 et la figure 3 montrent chacune un exemple d'appel de méthode virtuelle (la première sur un objet stocké dans une variable locale (ici un de ses arguments), la seconde, sur un champ virtuel) et la façon dont les appels aux méthodes "Tracer. methodlnvoke" et "Tracer. methodExit" peuvent y être insérés. Autrement dit, la classe "Tracer" maintient une pile de contextes qui évolue de la même façon que la pile d'appel de méthodes virtuelles (hors méthodes privées et constructeurs). La classe "Tracer" peut par exemple utiliser les objets "App l et" eux-mêmes pour représenter les contextes. La seule possibilité pour que le code d'une applet soit exécuté étant que l'une des méthodes virtuelles de l'applet soit appelée (par exemple, la méthode "Applet. p r o c e s s"), il est alors facile de voir que si on instrumente également, comme décrit ci-dessus, le code chargé d'effectuer ces appels (typiquement la partie implémentant le dispatcher de commandes APDU), et en considérant que le propriétaire d'un objet "Applet" est cette applet elle-même, l'applet dans le contexte de laquelle on entre sera effectivement empilée sur cette pile de contextes. La classe "Tracer" utilise également un objet particulier pour représenter le contexte système (ou contexte du JCRE) qui est le contexte associé à tous les objets de l'environnement qui n'ont pas été créés par des applets, mais par l'environnement d'exécution lui-même, lors de son initialisation. 2864651 - 12 - Ainsi, l'environnement est capable de connaître le contexte couramment actif et les méthodes "JCSystem.getAID" et "JCSystem. getPreviousContextAlD" sont capables de renvoyer respectivement l'AID associé au contexte couramment actif (AID de l'applet au sommet de la pile de contextes) et l'AID associé au contexte précédemment actif (en partant du sommet de la pile, AID de la première applet différente de l'applet au sommet de la pile) ; "JCSystem. getPreviousContextAlD" peut éventuellement retourner une référence nulle ("nul 1") lorsqu'il n'y a aucune autre applet dans la pile (cas où il n'y a aucun autre contexte actif avant celui de l'applet en dehors du contexte système ). Après ces différentes insertions dans le code exécutable, il est évidemment nécessaire de rétablir la cohérence des fichiers "Class" modifiés, notamment en ajoutant la description de la classe "Tracer" et de ses méthodes dans le Constant Pool de chacune des classes modifiées et en mettant à jour pour chacune des méthodes modifiées les tailles maximales de pile, les nombres maximaux de variables locales, les adresses utilisées par les instructions de branchement, les tables d'exceptions, les tables de numéros de lignes, etc. La description qui précède montre comment simuler un des mécanismes caractéristiques de la sémantique "Java Card" dans un environnement "Java". La simulation d'autres règles de la sémantique "Java Card" s'effectue de la même manière en insérant automatiquement d'autres instructions dans les fichiers "Class" et en ajoutant d'autres fonctions dédiées à la classe "Tracer". Dès lors qu'il devient possible de simuler la sémantique d'exécution de l'environnement "Java Card" dans l'environnement "Java", il ne reste plus qu'à développer une implémentation de l'API "Java Card", et à reproduire les mécanismes "Java Card" permettant l'installation et l'utilisation des applets, pour que les applets "Java Card" puissent s'exécuter dans l'environnement 2864651 - 13 - "Java" avec une sémantique d'exécution semblable à celle de l'environnement "Java Card". Il devient ainsi possible de développer de façon simple un simulateur de carte à puce conforme à la technologie "Java Card" et fonctionnant dans l'environnement "Java" sur PC. - 14 - Revendications 1. Procédé permettant de simuler, totalement ou partiellement, l'exécution de programmes écrits pour un environnement dit d'origine , à 5 l'aide d'un environnement dit de référence , caractérisé en ce qu'il consiste à : - à modifier de façon automatisée tout ou partie desdits programmes en y insérant des actions supplémentaires destinées à simuler certains aspects 10 dudit environnement d'origine; - à ajouter à l'environnement de référence des services (bibliothèques de fonctions) proposés par l'environnement d'origine et nécessaires à l'exécution desdits programmes. 2. Procédé selon la revendication 1, caractérisé en ce que lesdites actions supplémentaires sont des appels à des bibliothèques de fonctions ajoutées à l'environnement de référence dans le but de simuler certains aspects de l'environnement d'origine. 3. Procédé selon la revendication 1, caractérisé en ce que la modification automatique des programmes réalise également un changement du format desdits programmes de manière à les rendre compatibles avec le format d'exécution de l'environnement de référence. 4. Procédé selon l'une des revendications 1 et 3, caractérisé en ce que la modification automatique des programmes est effectuée avant leur chargement dans l'environnement de référence. 2864651 - 15 - 5. Procédé selon l'une revendications 1 et 3, caractérisé en ce que la modification automatique des programmes est effectuée au moment de leur chargement ou de leur installation dans l'environnement de référence. 6. Procédé selon l'une des revendications 1 et 3, caractérisé en ce que la modification automatique des programmes est effectuée au moment de leur exécution. 7. Procédé selon l'une des revendication 1 et 2, caractérisé en ce que certaines actions supplémentaires ou fonctions de bibliothèques réalisent une mise en oeuvre approchée de certaines fonctionnalités de l'environnement d'origine. 8. Procédé selon la revendication 1, caractérisé en ce que lesdits programmes sont des applications autonomes (ou applets ). 9. Procédé selon la revendication 1, caractérisé en ce que lesdits programmes sont des fonctions de bibliothèques. 10. Procédé selon l'une des revendications précédentes, caractérisé en ce que l'environnement d'origine ou l'environnement de référence (ou les deux) appartient à la famille "Java". 11. Procédé selon l'une des revendications précédentes, caractérisé en ce que l'environnement d'origine ou l'environnement de référence (ou les deux) appartient à la famille.NET. 2864651 -16- 12. Procédé selon l'une des revendications précédentes, caractérisé en ce que l'environnement d'origine est destiné à s'exécuter sur un petit dispositif du type carte à puce, téléphone mobile, assistant personnel (PDA).