Einführung in die GNU-Toolchain
Transcription
Einführung in die GNU-Toolchain
Einführung in die GNU-Toolchain Michael Schiefer, Christoph Steup Eingebettete Systeme und Betriebssysteme (EOS) Otto-von-Guericke-Universität Magdeburg Sommersemester 2014 Schiefer, Steup OvGU Magdeburg IVS-EOS Einführung in die GNU-Toolchain SS14 1/1 Überblick diese Woche GNU-Toolchain GDB QEMU C/C++-Einführung nächste Woche Organisatorisches OOStuBS Programmierung danach meist Abgaben Theorie und Praxis im Wechsel mehr dazu nächste Woche Schiefer, Steup OvGU Magdeburg IVS-EOS Einführung in die GNU-Toolchain SS14 2/1 GNU-Toolchain GNU-Toolchain I Ziele Erzeugung lauffähiger Programme/Bibliotheken aus Quellcode Architekturunabhängigkeit Abarbeitung aller Schritte autonom ohne Benutzereingriff Tools Buildsystem : GNU Make (make) Präprozessor : Gnu Compiler Collection (gcc) Compiler : GNU Compiler Collection (gcc/g++) Assembler : GNU Binutils - Assembler (gas) Linker : GNU Binutils - Linker (ld) Schiefer, Steup OvGU Magdeburg IVS-EOS Einführung in die GNU-Toolchain SS14 3/1 GNU-Toolchain GNU-Toolchain II *.o *.h Präprozessor C/C++ Compiler *.c[c] *.o prog Linker Assembler *.o GNU Make Makefile Schiefer, Steup OvGU Magdeburg IVS-EOS Einführung in die GNU-Toolchain SS14 4/1 GNU-Toolchain GNU Make GNU Make (make) allgemeiner Aufruf: make <Ziel> Steuerung durch Datei "Makefile" regelbasierte Syntax Ablauf einer Regel 1 Auflösen der Abhängigkeiten 2 Überprüfung auf Aktualität 3 Ausführen der Befehle Beispiel - einfache Makefile TARGET=e x a m p l e SOURCES=e x a m p l e . c c a s s e m b l e r . S $ {TARGET } : $ {SOURCES} $ {CXX} $ {CFLAGS} $^ −o $@ Schiefer, Steup OvGU Magdeburg IVS-EOS Einführung in die GNU-Toolchain SS14 5/1 GNU-Toolchain GNU Compiler Collection GNU Compiler Collection (gcc/g++) Übersetzung in ausführbaren Maschinencode (Programme/Bibliotheken) Aufruf für C: gcc <datei.c> Aufruf für C++: g++ <datei.cc> -Wall Ausgabe von allen Warnungen -o <datei> Name der zu erzeugenden Datei, sonst a.out -g Einbinden von Debug-Informationen für GDB -O[0|1|2|3|s] Optimierungsstufen Wenn nur Teilschritte ausgeführt werden sollen: -c nur Objekt-Code erzeugen -S nur Assembler-Code erzeugen -E nur Präprozessor ausführen Schiefer, Steup OvGU Magdeburg IVS-EOS Einführung in die GNU-Toolchain SS14 6/1 GNU-Toolchain Präprozessor Präprozessor (gcc/g++) Textuelle Ersetzung zur Vorverarbeitung Einsatzzwecke Bedingte Übersetzung (z.B. systemspezifische Teile) Auflösen von Makros (für C++ kaum von Bedeutung) Definition von Konstanten (unter C++ unschön) Häufige Präprozessor Direktiven #include <Datei> Einbinden von Header-Dateien #define <Name> <Wert> Definition von Konstanten und Makros Bedingte Übersetzung des folgenden Codeblocks: #if <Bedingung> Test auf Bedingung #ifdef <Name> Test ob Name bereits definiert #ifndef <Name> Gegenteil zu #ifdef <Name> #else Alternative #endif Ende eines bedingt Codeblocks Schiefer, Steup OvGU Magdeburg IVS-EOS Einführung in die GNU-Toolchain SS14 7/1 GNU-Toolchain GNU Assembler GNU Assembler (gas) Aufruf über gcc: gcc <Datei.S> direkter Aufruf: as <Datei.S> Beispiel - einfache Assembler-Datei . data base : zero : one : . long 0 . long 1 /∗ B e g i n d e s C o de s ∗/ . text . global /∗ B e g i n d e r D a t e n d e f i n i t i o n ∗/ /∗ L a b e l ∗/ /∗ r e s e r v i e r e n von v o r b e l e g t e m S p e i c h e r ∗/ return1 return1 : /∗ E x t e r n /∗ B e g i n mov $ b a s e , %e c x movl 4(% e c x ) , %e a x ret v e r f u e g b a r e S y m b o l e ∗/ einer F u n k t i o n ∗/ /∗ R u e c k s p r u n g ∗/ Schiefer, Steup OvGU Magdeburg IVS-EOS Einführung in die GNU-Toolchain SS14 8/1 GNU-Toolchain GNU Linker GNU Linker (ld) Syntax Aufruf über gcc: gcc < Datei1.o Datei2.o .. > -o <output> direkter Aufruf: ld < Datei1.o Datei2.o .. > -o <output> Aufgabe: Auflösen von unbekannten Symbolen zwischen Objektdateien kann über Skriptdatei gesteuert werden, für Betriebssystem nötig Bei Aufruf über gcc zusätzliche interne Schritte zur Erzeugung von Programmen Schiefer, Steup OvGU Magdeburg IVS-EOS Einführung in die GNU-Toolchain SS14 9/1 GNU-Toolchain GNU Debugger GNU Debugger: gdb Aufruf: gdb <Programm> Mächtiges Werkzeug zur Analyse vom Programmverhalten Graphische Oberflächen für gdb: ddd (Data Display Debugger) insight Wichtige Befehle help [<Parameter>] Hilfstext ausgeben break <Funktion> Programm gezielt unterbrechen run <Parameter> Programm starten continue Programm fortsetzen kill Programm abbrechen print <Ausdruck> Programmvariablen ausgeben Schiefer, Steup OvGU Magdeburg IVS-EOS Einführung in die GNU-Toolchain SS14 10 / 1 GNU-Toolchain GNU Debugger GNU Debugger II meist existieren Kurzformen für Befehle (continue, cont, c) Weitere Befehle backtrace Aufrufhierarchie verfolgen list Quellcodezeilen auflisten next [Anzahl] geht Anzahl (default 1) Schritte weiter step [Anzahl] wie next, nur geht es auch in Unterfunktionen disass Disassemblieren x/[Format] ∗[Adresse] Bytes an Adresse im Format ausgeben info locals lokale Variablen ausgeben info r Werte der Register ausgeben set [Name] = [Wert] Variable Name auf Wert setzen ··· Schiefer, Steup OvGU Magdeburg IVS-EOS Einführung in die GNU-Toolchain SS14 11 / 1 GNU-Toolchain QEMU Emulator Emulator QEMU Multi-Architektur Emulator Emulation von x86-CPU sowie Peripherie: Chipsatz (Intel i440FX) Grafikkarte (Standard VGA oder Cirrus CLGD 5446) Eingabegeräte (PS/2 Tastatur und Maus) Netzwerkkarten (e1000) Soundkarten (AC97, ES1370 oder Creative Soundblaster 16) verschiedene Ports (USB, Seriell, Parallel) Besondere Features: direktes Laden von Betriebssystemkernen (QEMU > 0.10) Debugging mithilfe von GDB Skriptfähig, da Konsolenanwendung Schiefer, Steup OvGU Magdeburg IVS-EOS Einführung in die GNU-Toolchain SS14 12 / 1 Programmiersprache C / C++ Programmiersprache C / C++ C ist meist verwendeten Sprachen obwohl relativ alt (erste Version ab 1971) Fast alle gängigen Betriebssysteme in C/C++ geschrieben Sehr maschinennahe Sprache, deshalb gut für Systemprogrammierung geeignet C++ syntaktisch zu C kompatibel aber mächtiger Schiefer, Steup OvGU Magdeburg IVS-EOS Einführung in die GNU-Toolchain SS14 13 / 1 Programmiersprache C / C++ Programmiersprache C / C++ C ist meist verwendeten Sprachen obwohl relativ alt (erste Version ab 1971) Fast alle gängigen Betriebssysteme in C/C++ geschrieben Sehr maschinennahe Sprache, deshalb gut für Systemprogrammierung geeignet C++ syntaktisch zu C kompatibel aber mächtiger Fazit: Wer sich mit Systemprogrammierung beschäftigt, kommt um C/C++ nicht herum! Schiefer, Steup OvGU Magdeburg IVS-EOS Einführung in die GNU-Toolchain SS14 13 / 1 Programmiersprache C / C++ Datentypen Typisierung und Deklaration Jede Variable hat eindeutigen Typ der mögliche Anweisungen/Befehle bestimmt Trennung von Deklaration und Definition Compiler überwacht korrekte Typisierung Bei inkompatiblen Datentypen Umwandlung nötig: implizite/explizite casts Syntax: [Spezifizierer] Basistyp[Modifikator] Objektname[Modifikator]; Spezifizierer Veränderung der internen Repräsentation (const, extern, static, volatile) Modifikator Veränderung des Typs (Zeiger *, Referenz &, Array [], Funktion ()) Beispiel – Deklaration und Definition s t r i n g output ; output = " Test1 " ; Schiefer, Steup OvGU Magdeburg IVS-EOS Einführung in die GNU-Toolchain SS14 14 / 1 Programmiersprache C / C++ Datentypen Basisdatentypen in C C kennt folgende Datentypen, Größen für x86-Architektur char c; short s; int i ; long l ; long long ll ; float f; double d; long double ld ; /∗ /∗ /∗ /∗ /∗ /∗ /∗ /∗ 8 16 32 32 64 32 64 128 Bit Bit Bit Bit Bit Bit Bit Bit , A chtung : ∗/ ∗/ ∗/ ∗/ , A chtung : , A chtung : , Achtung : standardmaessig i n OOStuBs n i c h t i n OOStuBs n i c h t i n OOStuBs n i c h t s i g n e d ∗/ v e r w e n d e n ∗/ v e r w e n d e n ∗/ v e r w e n d e n ∗/ Unsigned und Signed Variante für jeden ganzzahligen Typ Größe der Datentypen systemabhängig, wobei gilt: int ist natürliche Größe der Plattform short ≤ int ≤ long Tatsächliche Größe eines Datentyps mit Operator sizeof (Datentyp|Variable) in Bytes Schiefer, Steup OvGU Magdeburg IVS-EOS Einführung in die GNU-Toolchain SS14 15 / 1 Programmiersprache C / C++ Datentypen Datentyp bool Kein expliziter Datentyp bool in ANSI-C Als Erweiterung in C definiert, in C++ Standard implizite Konvertierung (0 = false und 0 6= true) Beispiel – bool int int t =1; f =0; int main ( ) { if (t) p r i n t f ( " t r u e \n" ) ; i f (! f ) p r i n t f ( " f a l s e \n" ) ; } Schiefer, Steup OvGU Magdeburg IVS-EOS Einführung in die GNU-Toolchain SS14 16 / 1 Programmiersprache C / C++ Datentypen Enumerationen Deklaration von Aufzählungen Alternativ auch zur Konstantendefinition mit sprechenden Namen ist Menge von Integer-Konstanten Verwendung äquivalent zu int Definierte Enumerationen sind jeweils eigener Typ Beispiel - enum enum T e x t I n d i c e s { Object , Interface , Test1 , Test2 }; const v o i d ∗ g e t T e x t ( enum T e x t I n d i c e s Schiefer, Steup OvGU Magdeburg IVS-EOS index ); Einführung in die GNU-Toolchain SS14 17 / 1 Programmiersprache C / C++ Funktionen Funktionen in C Definition syntaktisch wie Methodendefinition in Java Auch hier Trennung von Deklaration und Definition möglich Es können nur bereits deklarierte Funktionen verwendet werden! Trennung von Interface und Implementierung: Definitionen in Header-Dateien, beschreibt Interface Definition in C-Dateien, beschreibt Implementierung Funktionsdeklaration const v o i d ∗ g e t T e x t ( enum T e x t I n d i c e s index ); Funktionsdefinition c o n s t v o i d ∗ g e t T e x t ( enum T e x t I n d i c e s r e t u r n Text [ i n d e x ] ; } Schiefer, Steup OvGU Magdeburg IVS-EOS i n d e x ){ Einführung in die GNU-Toolchain SS14 18 / 1 Programmiersprache C / C++ Funktionen Gültigkeitsbereich und Allokation I Definition Ein Codeblock ist ein von { und } eingeschlossener Bereich des C/C++-Codes Gültigkeitsbereiche lokal, innerhalb eines Codeblocks global, außerhalb von allen Codeblöcken Zugriff auf Variablen nur auf gleicher oder in weiteren Verschachtlungsebene Umdeklaration von Variablen in verschachtelten Blöcken ist möglich, jedoch schlechter Stil Schiefer, Steup OvGU Magdeburg IVS-EOS Einführung in die GNU-Toolchain SS14 19 / 1 Programmiersprache C / C++ Funktionen Gültigkeitsbereich und Allokation II Allokation lokale Variablen werden auf dem Stack alloziert globale Variablen liegen im Datensegment der ausführbaren Datei Modifikation des Standardverhaltens extern deklarierte Variablen, werden nicht erzeugt, ihre Existenz wird vorausgesetzt static deklarierte lokale Variablen behalten ihren Wert auch bei Verlassen der Gültigkeit static deklarierte globale Variablen gelten nur in der Datei in der sie definiert wurden Schiefer, Steup OvGU Magdeburg IVS-EOS Einführung in die GNU-Toolchain SS14 20 / 1 Programmiersprache C / C++ Klassen und Objekte Klassendeklaration Klassendeklaration ist eine C++ Typdeklaration (Wichtig: Semikolon am Ende) Nahezu identisch zu Java, jedoch : statt extends oder implements Zugriffskontrolle durch public, protected, private (Standard: private) Beispiel – Klassendeklaration c l a s s DataPrinter : public private : o s t r e a m& o u t ; public : void printOne ( ) ; }; DataPrinterInterface { Schiefer, Steup OvGU Magdeburg IVS-EOS Einführung in die GNU-Toolchain SS14 21 / 1 Programmiersprache C / C++ Klassen und Objekte Zugriff auf Felder und Methoden Objekte verwenden den Operator . (Punkt) Objektzeiger verwenden den Operator -> (Pfeil) Aktuelles Objekt spricht Felder/Methoden direkt an Alternativer Zugriff mit this-Zeiger Beispiel - Zugriff o s t r e a m& D a t a P r i n t e r : : o p e r a t o r <<(Data &d ) { o u t << d . s << e n d l ; } void DataPrinter : : printOne (){ t h i s −>o u t << " one : ␣ " << r e t u r n 1 ( ) << e n d l ; } Schiefer, Steup OvGU Magdeburg IVS-EOS Einführung in die GNU-Toolchain SS14 22 / 1 Programmiersprache C / C++ Klassen und Objekte Strukturen und Unions struct Strukturdeklaration durch struct, abwärtskompatibel zu C In C++ entspricht Klasse mit Standardzugriff public Reihenfolge der Elemente wird vom Compiler nicht verändert Compiler kann freie Speicherstellen zwischen den Elementen einfügen union Eine union vereint mehrere Interpretationen eines Stück Speichers in einem Typ Syntaktisch äquivalent zu Strukturen die Gesamtgröße entspricht der Größe des größten Elements Jedes Element entspricht einer Interpretation des darunter liegenden Speichers Schiefer, Steup OvGU Magdeburg IVS-EOS Einführung in die GNU-Toolchain SS14 23 / 1 Programmiersprache C / C++ Klassen und Objekte Beispiel: Strukturen und Unions Beispiel - struct s t r u c t Data { string s ; }; Beispiel - union u n i o n DataUnion { Data d a t a ; const void∗ ptr ; }; Schiefer, Steup OvGU Magdeburg IVS-EOS Einführung in die GNU-Toolchain SS14 24 / 1 Programmiersprache C / C++ Objekt-Orientierung Überladen von Operatoren Operatoren sind in C++ Methodenaufrufe Überladen wie in Java Nur bestehende Operatoren überladbar Priorität und Assoziativität von Operanden nicht veränderbar Beispiel - Überladung von « c l a s s DataPrinter : public DataPrinterInterface { public : v i r t u a l o s t r e a m& o p e r a t o r <<( c o n s t v o i d ∗ a d d r e s s ) ; }; Schiefer, Steup OvGU Magdeburg IVS-EOS Einführung in die GNU-Toolchain SS14 25 / 1 Programmiersprache C / C++ Operationen auf Typen typedef Verwendung: typedef <Definition> <Typenname> Umbenennen von Datentype Definition eigener Datentypen Beispiel - typedef typedef const char∗ s t r i n g ; Schiefer, Steup OvGU Magdeburg IVS-EOS Einführung in die GNU-Toolchain SS14 26 / 1 Programmiersprache C / C++ Operationen auf Typen Casts implizite: führt der Compiler automatisch durch explizite: werden vom Programmierer angefordert: C-Cast: (<neuer Typ>)<variable> unsicher → nicht verwenden C++-Casts: spezielle Checks, daher error bei invaliden Casts (<> gehören zur Syntax) : const_cast<neuer Typ>(Variable) Cast von const Objekt zu nicht const Objekt static_cast<neuer Typ>(Variable) Cast die Vererbungskette hinab, Check zur Compile-Zeit dynamic_cast<neuer Typ>(Variable) Cast die Vererbungskette hinab, Check zur Laufzeit reinterpret_cast<neuer Typ>(Variable) für alles andere Beispiel - cast s t r i n g output ; c o n s t v o i d ∗ p t r=r e i n t e r p r e t _ c a s t <c o n s t Schiefer, Steup OvGU Magdeburg IVS-EOS v o i d ∗>( o u t p u t ) ; Einführung in die GNU-Toolchain SS14 27 / 1 Programmiersprache C / C++ Zeiger und Referenzen Zeiger und Referenzen Achtung Eine der wichtigsten Fehlerquellen in C/C++ sind Zeiger! Grund: Unkontrollierter Zugriff auf beliebige Speicherstellen Programmabbruch durch das Betriebssystem (gut!) Überschreiben beliebiger Daten (schlecht!) Fehler durch falsche Zeiger sind oft sehr schwer zu finden Schiefer, Steup OvGU Magdeburg IVS-EOS Einführung in die GNU-Toolchain SS14 28 / 1 Programmiersprache C / C++ Zeiger und Referenzen Beispiele int *p 255 int **p 255 char name[] int argc H a l r m - r l o 4 char **argv Schiefer, Steup OvGU Magdeburg IVS-EOS f Einführung in die GNU-Toolchain SS14 29 / 1 Literatur Literatur I Schiefer, Steup OvGU Magdeburg IVS-EOS Einführung in die GNU-Toolchain SS14 30 / 1 Anhang Beispiel Projekt: Makefile und Assembler-Code Makefile TARGET=e x a m p l e SOURCES=e x a m p l e . c c a s s e m b l e r . S $ {TARGET } : $ {SOURCES} $ {CXX} $ {CFLAGS} $^ −o $@ Assembler Code (assembler.S) . data base : zero : one : . long 0 . long 1 /∗ B e g i n d e s C o de s ∗/ . text . global /∗ B e g i n d e r D a t e n d e f i n i t i o n ∗/ /∗ L a b e l ∗/ /∗ r e s e r v i e r e n von v o r b e l e g t e m S p e i c h e r ∗/ return1 return1 : /∗ E x t e r n /∗ B e g i n mov $ b a s e , %e c x movl 4(% e c x ) , %e a x ret v e r f u e g b a r e S y m b o l e ∗/ einer F u n k t i o n ∗/ /∗ R u e c k s p r u n g ∗/ Schiefer, Steup OvGU Magdeburg IVS-EOS Einführung in die GNU-Toolchain SS14 31 / 1 Anhang Beispiel Projekt: example.h I #i f n d e f __example_header__ #d e f i n e __example_header__ #i n c l u d e <i o s t r e a m > using using using using std std std std typedef :: :: :: :: cout ; hex ; endl ; ostream ; const char∗ s t r i n g ; enum T e x t I n d i c e s { Object , Interface , Test1 , Test2 }; const v o i d ∗ g e t T e x t ( enum T e x t I n d i c e s index ); s t r u c t Data { string s ; }; Schiefer, Steup OvGU Magdeburg IVS-EOS Einführung in die GNU-Toolchain SS14 32 / 1 Anhang Beispiel Projekt: example.h II u n i o n DataUnion { Data d a t a ; const void∗ ptr ; }; class DataPrinterInterface { public : v i r t u a l ~DataPrinterInterface (); v i r t u a l o s t r e a m& o p e r a t o r <<(Data &d ) = 0 ; v i r t u a l o s t r e a m& o p e r a t o r <<( c o n s t v o i d ∗ a d d r e s s ) = 0 ; }; c l a s s DataPrinter : public DataPrinterInterface { private : o s t r e a m& o u t ; public : DataPrinter ( ) ; v i r t u a l ~DataPrinter ( ) ; void printOne ( ) ; v i r t u a l o s t r e a m& o p e r a t o r <<(Data &d ) ; v i r t u a l o s t r e a m& o p e r a t o r <<( c o n s t v o i d ∗ a d d r e s s ) ; }; e x t e r n "C" u n s i g n e d #e n d i f int return1 (); Schiefer, Steup OvGU Magdeburg IVS-EOS Einführung in die GNU-Toolchain SS14 33 / 1 Anhang Beispiel Projekt: example.cc I #i n c l u d e " e x a m p l e . h " static const c h a r ∗ T e x t [ ] = { "Tod␣ d e s ␣ O b j e c t s " , "Tod␣ d e s ␣ I n t e r f a c e s " , " Test1 " , " Test2 " } ; c o n s t v o i d ∗ g e t T e x t ( enum T e x t I n d i c e s r e t u r n Text [ i n d e x ] ; } DataPrinter : : DataPrinter () } : i n d e x ){ DataPrinterInterface () , out ( cout ){ DataPrinter ::~ DataPrinter (){ c o n s t c h a r ∗ t e x t = ( c o n s t c h a r ∗) g e t T e x t ( O b j e c t ) ; c o u t << t e x t << e n d l ; } DataPrinterInterface ::~ DataPrinterInterface (){ c o u t << ∗ ( T e x t+ I n t e r f a c e ) << e n d l ; } o s t r e a m& D a t a P r i n t e r : : o p e r a t o r <<(Data &d ) { o u t << d . s << e n d l ; } o s t r e a m& D a t a P r i n t e r : : o p e r a t o r <<( c o n s t o u t << h e x << a d d r e s s << e n d l ; } Schiefer, Steup OvGU Magdeburg IVS-EOS v o i d ∗ a d d r e s s ){ Einführung in die GNU-Toolchain SS14 34 / 1 Anhang Beispiel Projekt: example.cc II void DataPrinter : : printOne (){ t h i s −>o u t << " one : ␣ " << r e t u r n 1 ( ) << e n d l ; } s t r i n g output ; c o n s t v o i d ∗ p t r=r e i n t e r p r e t _ c a s t <c o n s t v o i d ∗>( o u t p u t ) ; DataUnion u ; i n t main ( ) { DataPrinter print ; output = " Test1 " ; u . p t r = Text [ Test1 ] ; p r i n t << u . d a t a ; c o u t << "&(" << o u t p u t << " ) : ␣ " << p t r << e n d l ; o u t p u t = r e i n t e r p r e t _ c a s t <c o n s t c h a r ∗>( g e t T e x t ( T e s t 2 ) ) ; c o u t << "&(" << o u t p u t << " ) : ␣ " << p t r << e n d l ; return 0; } Schiefer, Steup OvGU Magdeburg IVS-EOS Einführung in die GNU-Toolchain SS14 35 / 1