• Keine Ergebnisse gefunden

4.4 Code Management Framework

4.4.2 Macro-Interface

DasMI (Macro-Interface)besteht aus einer auf Makros basierten Schnittstelle des CMF. Das MI unterteilt sich in dasDefMI (Definition Macro-Interface)undCallMI (Call Macro-Interface).

53Die Funktionmy_Funckönnte z. B. die Methode eines Crypto-Objektes sein.

54Lesezugriffe auf eine Variable sind durch grüne, Schreibzugriffe durch rote Pfeile kenntlich gemacht.

Kapitel 4 CRYPTO-COMPILER

1externvoidfunc(int&);23//DefMI4CM_CODE_DEFINITIONS_BLOCK_BEGIN5CMD_TYPE(bnz_t,bnz_t)6CMD_COPYABLE_TYPE(int,int)7CMD_PROCEDURE_o1(func,int)8CM_CODE_DEFINITIONS_BLOCK_END910//FunktionmitmarkiertenAnweisungen11voidmy_Func()12{13inti;14//MarkiereneineraufzusammelndenVariable15CMV(intccI);16//Zuweisung17ccI=CMV_IN(3);18//Funktionsaufrufausführen,nichtaufsammeln19func(i);20//MarkiereneinesaufzusammelndenFunktionsaufrufes21CMI(func(ccI));22}2324voidmain()25{26//nurausführenderFunktion27my_Func;28//ausführenundaufsammeln29CodeCollectorcc(collector);30cc.beginSubProgram(collected);31my_Func();32cc.endSubProgram(collected);33//ZugriffaufdenZwischencode34ProgramCCR&rProgram=cc.getProgram();35}

Listing4.1:Einführungsbeispiel iVar1(int)

iVar2(int) iVar1

Constructor

iVar2=3

Constructor

iVar1=iVar2

CopyAssignment

iVar2

DestructorCall

func

Procedure

iVar1

DestructorCall

ProgramCCR-collected

Code Management Framework 4.4

CallMI

1 // CMV ( int ccI );

2 CMV: : __cm_int ccI (CM_CREATE_DEBUG_INFO(..) );

3 // CMV_POINTER ( int , ccI2 );

4 CMV: : __cm_PointerBox_int ccI2 (CM_CREATE_DEBUG_INFO(..) );

5 // CMV_ARRAY ( int , ccI3 , 2) ;

6 CMV: : __cm_int ccI3 ( new vector <CMV: : __cm_int * >() , 2, ë CM_CREATE_DEBUG_INFO(..) );

7 // CMI ( func ( ccI ));

8 CMI: : func ( ccI ). call (CM_CREATE_DEBUG_INFO(..) );

Listing 4.2:Auflösung der wichtigsten CallMI-Makros.

Die MakrosCMVundCMIwerden als CallMI-Makros bezeichnet und dienen zur Markierung der aufzusammelnden Anweisungen im Quellcode. Listing 4.2 zeigt die Auflösung der Makros.

Das MakroCMVerzeugt für die eingeschlossene Variable ein CCW im CMF-Na-mensraum (Zeile 1 / 2, siehe Kapitel 4.4.3)55. Für jeden Funktionsaufruf existiert ein CCW im CMF.

Um das Verhalten von Zeigern zu abstrahieren, steht zusätzlich das CallMI-Ma-kroCMV_POINTERzur Verfügung. Dadurch verhält sich die VariableccI2wie eine kopierbare Variable, dessen Wert der Adresse von Daten auf dem Heap entspricht (Zeile 3 / 4).

Arrays werden über dasCMV_ARRAY-Makro definiert (Zeile 5 / 6). Es werden jeweils ein CCW für die Array-Variable sowie alle Array-Elemente erstellt.

Das MakroCMI(func)ruft zur Registrierung des Funktionsaufrufes das passende CCW auf (Zeile 7 / 8).

Die CallMI-Makros übergeben über das MakroCM_CREATE_DEBUG_INFO zusätz-lich Debugging-Informationen an die CCWs. Dazu gehören z. B. der Name der Quelldatei und die Zeile, in der die Anweisung markiert wurde. Im kompilierten Code lassen sich daraus Kommentare erzeugen, um das Debugging zu erleich-tern.

Das CallMI verfügt über weitere Makros, die in den folgenden Kapiteln genau-er beschrieben wgenau-erden. Das MakroCMV_INimportiert Konstanten oder Werte nicht-markierter Variablen in das CMF, während das MakroCMV_OUTWerte von Variablen aus dem CMF exportiert (Kapitel 4.4.8). Weitere Makros stehen zur Be-schreibung von Verzweigungen und Schleifen (Kapitel 4.4.10) zur Verfügung.

55Die CCWs befinden sich in einem eigenen Namensraum (CMV::für Variablen,CMI::für Instruktionen), um nicht mit den Bezeichnern im Quellcode zu kollidieren. Des Weiteren haben alle Typen der CCWs das Prefix__cm_, da CCWs C++Objekte sind und Namen von Basistypen (z. B.int) als Klassennamen verboten sind.

Kapitel 4 CRYPTO-COMPILER

DefMI

1 typedef const char * str ;

2 extern str * str_Cstr ( str rInitConst );

3 extern void str_Dest ( str * pThis );

4

5 extern void bnz_init ( bnz_t &) ;

6 extern void bnz_set ( bnz_t &, const bnz_t &) 7 extern int bnz_set_Str ( bnz_t &, str , int );

8 extern int hashUpdateBnz (POINTER( HashContext )&, const bnz_t &) 9

10 CM_CODE_DEFINITIONS_BLOCK_BEGIN 11 CMD_TYPE( bnz_t )

12 CMD_TYPE( HashContext ) 13 CMD_COPYABLE_TYPE( int ) 14 CMD_COPYABLE_TYPE( str )

15 CMD_CONST_INSTANCES_HANDLING( str , str_Cstr , str_Dest ) 16

17 CMD_PROCEDURE_o1( bnz_init , false , true , bnz_t )

18 CMD_PROCEDURE_o1i1( bnz_set , false , false , bnz_t , bnz_t ) 19 CMD_FUNCTION_o1i2( int , bnz_set_Str , false , false ,

ë bnz_t , str , int )

20 CMD_FUNCTION_o1i1( int , hashUpdateBnz , false , false , ë POINTER( HashContext ) , bnz_t ) 21 CM_CODE_DEFINITIONS_BLOCK_END

Listing 4.3:Beispiel zur Nutzung des DefMI.

Aufzusammelnde Variablen und Funktionsaufrufe werden durch dieCMV- und CMI-Makros auf CCWs im CMF abgebildet. Ein CCW ist ein C++Objekt dessen Typ vom Typ der aufzusammelnden Variablen bzw. vom Prototyp der aufzusam-melnden Funktion abhängig ist. Das DefMI definiert diese Typen. Nur durch das DefMI definierte Variablentypen und Funktionsaufrufe sind aufsammelbar.

DefMI-Definitionen werden durchDefinitionsblöckezusammengefasst. Ein C++

Projekt kann mehrerer solcher Definitionsblöcke enthalten, die üblicherweise in den Header-Dateien, in denen die Typen und Funktionen deklariert sind, stehen.

Das Listing 4.3 zeigt beispielhaft einen DefMI-Definitionsblock für die drei Typenint,bnz_t56undstrsowie mehrere Funktionen. Durch das MakroCM_

CODE_DEFINITIONS_BLOCK_BEGIN57in Zeile 10 wird der DefMI-Definitionsblock eingeleitet und durch das Makro in Zeile 21 beendet.

56Der Typbnz_trepräsentiert im Crypto-Compiler eine Langzahl. Bei Funktionen kennzeichnet das Präfixbnz_Operationen, die auf Variablen vom Typbnz_tangewendet werden [71].

57Zusätzlich gibt es das MakroCM_CODE_DEFINITIONS_BLOCK_EX_BEGIN(namespace), das inner-halb des Definitionsblockes Zugriff auf den Namensraumnamespacegestattet.

Code Management Framework 4.4

Das CMF unterscheidet zwischeneinfachen(Zeile 11) und kopierbaren Varia-blen (Zeile 13 / 14). Kopierbare VariaVaria-blen-CCWs58 kann über den Ist-gleich-Operator ein neuer Wert zugewiesen werden. Bei nicht-kopierbaren bzw. einfa-chen CCW-Variablen ist das nicht möglich, sondern nur über ihren Kopierkon-struktor (siehe Kapitel 4.4.8)59.

Einen Sonderfall stellt der Typstrzur Repräsentation von C-Zeichenketten im CMF dar. Variablen des Typs speichern nur die Anfangsadresse eines Arrays voncharWerten. Soll z. B. eine konstante Zeichenkette über dasCMV_IN-Makro importiert werden (siehe Kapitel 4.4.8), würde nur die Speicheradresse kopiert.

Eineflache Kopiewird erstellt [159]. Das MakroCMD_CONST_INSTANCES_HANDLING in Zeile 15 definiert deshalb spezielle Konstruktor- und Destruktoraufrufe, die aufgerufen werden, sobald Variablen des angegebenen Typs erzeugt bzw. zer-stört werden. Für den Typstrlegt der Konstruktorstr_Cstreinetiefe Kopieder Variablen an [159].

Zeile 17 bis 20 zeigt die Definition von Funktionsaufrufen im DefMI. Es wird zwischenProzedurenundFunktionenunterschieden. Funktionen, deklariert durch das MakroCMD_FUNCTION, haben einen Rückgabewert und entsprechen klassi-schen C++Funktionen mit return-Wert. Prozeduren dagegen, deklariert durch dasCMD_PROCEDURE-Makro, entsprechen C++Funktionen ohne Rückgabewert bzw. mit Rückgabewertvoid.

Im CMF werden Funktionen und Prozeduren alsInstruktionenbezeichnet. Auf-rufe von Instruktionen können Parameter besitzen, wobei zwischen Eingabe-und Ausgabeparametern unterschieden wird. Ausgabeparameter können wäh-rend der Ausführung der Instruktion verändert werden, bei Eingabeparametern ist das nicht möglich60. Die differenzierte Betrachtung ist insbesondere bei der Optimierung des Zwischencodes von Bedeutung (Kapitel 4.4.11).

Das Suffix im Bezeichner eines DefMI-Makros gibt die Anzahl der Eingabe- und Ausgabeparameter der Funktion bzw. Prozedur an. In Zeile 17 weist das Suffixo1 darauf hin, dass die Prozedur genau einen Ausgabeparameter (o, engl. output) hat.

Die Funktion in Zeile 19 hat dagegen zwei Eingabe- und einen Ausgabeparameter (i, engl. input).

Der erste Parameter imCMD_PROCEDURE-Makro gibt den Namen der C++ Funk-tion an, dessen Aufrufe aufgesammelt werden sollen. Der nächste Parameter spezifiziert, ob die AnweisungSeiteneffektehat, d. h. ob sich durch die Ausführung der Anweisung der Zustand (bis auf die Änderung der Ausgabeparameter) des Programmes ändert. Der dritte Parameter legt fest, ob es sich bei der Funktion

58Kopierbare Variablen-CCWs beschreiben Basistypen wie z. B.int,long,bool.

59Dazu gehören z. B. Variablen vom Typbnz_t, die nicht direkt kopiert werden können.

60Streng genommen kann eine Änderung der Variable immer noch explizit durch den Program-mierer mithilfe vonconst_castverändert werden [159].

Kapitel 4 CRYPTO-COMPILER

um einen speziellen Konstruktor-/Destruktoraufruf handelt61. Beide Parame-ter sind für die Optimierung des Zwischencodes relevant (Kapitel 4.4.11). Die folgenden Parameter geben die Variablentypen der Eingabe- und Ausgabepara-meter an, wobei die Typen der EingabeparaAusgabepara-meter als letztes deklariert werden.

Die Ausgabeparameter der aufzusammelnden Funktion werden immer als Refe-renzparameter übergeben62. Eingabeparameter müssen entweder als Referenz-(bei einfachen Variablen) oder als Wertparameter Referenz-(bei kopierbaren Variablen) definiert werden63.

Die Beschreibung der aufzusammelnden Instruktionen über das DefMI gewähr-leistet die Typsicherheit. Fehlerhafte Aufrufe werden bereits zur Kompilierzeit erkannt.

DasCMD_FUNCTION-Makro wird für das Aufsammeln der Funktionsaufrufe mit Rückgabewert verwendet. Es entspricht dem Aufbau desCMD_PROCEDURE-Makros.

Lediglich ein zusätzlicher Parameter am Anfang der Parameterliste definiert den Rückgabetyp (Zeile 19). Nur kopierbare Typen sind als Rückgabewert erlaubt.

Falls der Zeiger auf eine Variable als Parameter einer Instruktion übergeben wer-den soll, ist der Typ der Variablen mit dem MakroPOINTER(..)zu kennzeichnen (siehe Zeile 20).

Deaktivierung des CMF

1 int ccI ; // CMV ( int ccI );

2 int * ccI2 ; // CMV_POINTER ( int , ccI2 );

3 int ccI2 [2]; // CMV_ARRAY ( int , ccI2 , 2) ; 4 func ( ccI ); // CMI ( func ( ccI ));

Listing 4.4:Auflösung der in Listing 4.1 verwendeten CallMI-Makros bei Deaktivie-rung des CMF.

Während der Quellcode kompiliert wird, muss das MakroCM_ENABLE_CODE_

COLLECTINGglobal definiert sein, damit Anweisungen vom CMF aufgesammelt werden können. Soll das Crypto-Framework ohne Compiler-Funktionalität ver-wendet werden, wird das Makro nicht definiert und die Markierungen durch die CallMI-Makros durch den Präprozessor entfernt (siehe Listing 4.4). Bei der Ausführung des Crypto-Frameworks ohne Backend kommt es zu keinerlei Per-formanceeinbußen.

61Die Funktionenbnz_initundbnz_clearzur Erzeugung bzw. Zerstörung einer Langzahl sind spezielle Konstruktor- bzw. Destruktoraufrufe.

62Die Funktionbnz_init()hat nach Zeile 17 z. B. einen Ausgabeparameter. Der Prototyp der Funktion in Zeile 5 definiert den Parameter entsprechend als Referenzparameter.

63Variablen vom Typintwerden z. B. als Wertparameter während Variablen vom Typbnz_tals Referenzparameter übergeben werden (Zeile 14).

Code Management Framework 4.4

1 extern void func ( int );

2

3 void cc_ToCollect ()