Linker & Loader in .NET August Steinbacher
Vortragsüberblick C++ vs .NET Auffinden von Assemblies Execution Model Runtime Layout Methodenadressierung
Traditioneller Ansatz Compiler Frontend: Parsen der High-Level-Syntax Kompilieren in Zwischencode Compiler Backend: Zwischencode -> Native Code Platzhalter für imports & exports Linker: Erzeugen eines executable file Loader: Platzieren des Executables im Speicher App1.cpp App2.cpp Incl.h Compiler Objekt datei Objekt datei Linker EXE Datei Loader Image in MEM
.NET Modell Compiler Frontend: Compiler Backend (CLR): Parsen der High-Level-Syntax Erzeugen von Zwischencode + Metadaten Assemblies Compiler Backend (CLR): Lokalisieren des Assemblies Erzeugen von Native Code Kompilieren Linken Laden Source Source Compiler Compiler Assemblies CLR Processes Memory
Ausführen von .NET .exe Datei starten Applikationsdomäne Windows-loader startet die CLR Applikation läuft innerhalb der CLR Applikationsdomäne Isoliert Applikationen voneinander Laden aller Assemblies, Module und Typen Methodentabellen der Typen Statische Felder und Objekte Side-by-Side Execution Eintrittspunkt Schlüsselwort .entrypoint in PE-Datei
3 Levels of Loading Laden der PE-Datei von Disk Laden des Assemblies Einziger Festplattenzugriff Enthält Metadaten Laden des Assemblies Aufgrund der Metadaten Sicherheitsmanager prüft Rechte Laden der Typen Classloader PE-Datei Assemblies String Integer Object
Lokalisieren von Assemblies Assembly Resolver Name des gesuchten Assemblies Versionsinformation Informationen über AppDomain Konfigurationsdateien Öffentliche Assemblies GAC Codebase-Hints in Konfigurationsdateien Private Assemblies Im Applikationsverzeichnis Probing
Lokalisieren von Assemblies Assembly.Load(name) Public Key? Probing erfolgreich? N In GAC? J Lade File aus GAC J <CodeBase> Vorhanden? N Passt File? J Lade File von <CodeBase> J Assembly.Load endet mit Fehler N Passt File? J Lade File J N N
Probing 4 Kriterien: Applikationsverzeichnis Culture-Attribut Assembly Name Relativer Suchpfad [AppDir] / [Assembly name].dll [AppDir] / [Assembly name] / [Assembly name].dll C:/App/code.dll C:/App/code/code.dll [AppDir] / [culture] / [Assembly name].dll [AppDir] / [culture] / [Assembly name] / [Assembly name].dll C:/App/en-US/code.dll C:/App/en-US/code/code.dll [AppDir] / [binpath] / [Assembly name].dll [AppDir] / [binpath] / [Assembly name] / [Assembly name].dll C:/App/shared/code.dll C:/App/shared/code/code.dll [AppDir] / [binpath] / [culture] / [Assembly name].dll [AppDir] / [binpath] / [culture] / [Assembly name] / [Assembly name].dll C:/App/shared/en-US/code.dll C:/App/shared/en-US/code/code.dll
Laden eines Typs T Durch Classloader Verifikation der Typsicherheit Bestimmung des benötigten Speicherplatzes Bestimmung des Speicherlayouts Auflösen von Referenzen auf bereits geladene Typen Stubs erzeugen für Methoden von T Methodenaufrufe lösen JIT-Kompilierung aus Verifikation der Typsicherheit 4 Kategorien Ungültig Gültig Typsicher Verifizierbar Ungültig Gültig Typsicher Verifizierbar
Execution Model PE Verifikation GAC AppDir Compiler Assembly Source Code Compiler csc, jsc,... Assembly PE File + MSIL + Metadaten Policy Manager Erteilte Rechte Assembly Loader Assembly Info Class List Assembly Method Class Class Loader Runtime Layout JIT Native Code
Objektinstanzen Heap Private EE Memory Instance of A Instance of B Instance Data Instance Data Instance Data Method Table A Method Table B Sync Block Table Private EE Memory
Runtime Layout Object Reference „Hot Data“ „Cold Data“ Instance Data Object Header Index Sync Block Table MethodTable GCDesc Interface map Module Class Loader Assembly App Domain Compiled method JMI thunk „Hot Data“ „Cold Data“ EEClass Prestub ptr Prestub FieldDesc MethodDesc
Method Table & Interface Map GCDesc MethodTable header Inherited virtuals Introduced virtuals Instance and static methods Method Table Interface Map 1 2 3 4 5 EEClass
Methodenadressierung interface I1 { m1(); m2(); } interface I2 { m2(); m3(); } Method Implementations A.m1; A.m2; class A : I1 { m1(){..}; m2(){..}; } A.m1; I1.m1 A.m2; I1.m2 A.m1; I1.m1; A.m2; I1.m2; B.m3; A.m1; I1.m1; A.m2; I1.m2; I2.m2 B.m3; I2.m3 B.m3; class B : A, I2 {m3(){..}; } class C : B { I2.m2() {..}; } A.m1; I1.m1; A.m2; I1.m2; B.m3; I2.m2; I2.m3;
Quellen Don Box, Chris Sells: Essential .NET, The Common Language Runtime, Addison-Wesley 2003 Dave Stutz, Ted Neward, Geoff Shilling: Shared Source CLI Essentials. O'Reilly 2003 W.Beer, D.Birngruber, H.Mössenböck, A.Wöß: Die .NET-Technologie, dpunkt.verlag 2002 http://www.msdn.microsoft.com/netframework/ http://www.dotnetframework.de http://dotnet.di.unipi.it/
Ende... ...Fragen?