So erhalten Sie den Anweisungszeiger (= Programmzähler) im Linux-Kernel

Wenn Sie den Anweisungszeiger (= Programmzähler) im Linux-Kerneltreiber erhalten möchten, verwenden Sie das in linux / kernel.h definierte Makro _THIS_IP_.

Die Definition ist wie folgt.

#define _THIS_IP_  ({ __label__ __here; __here: (unsigned long)&&__here; })

Eine kurze Geschichte von Instruction Pointer im Linux-Kernel

In der Vergangenheit hat jede Architektur ihre eigene "current_text_addr ()" definiert, aber es scheint, dass sie alle um v4.20 abgeschafft und vereinheitlicht wurden, um "THIS_IP" in linux / kernel.h zu verwenden. ist.

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?h=v5.6-rc2&id=de0d22e50cd3d57277f073ccf65d57aa519d6888

Wenn Sie sich den Patch zu diesem Zeitpunkt ansehen, ist es interessant zu sehen, wie der Assembler jeder Architektur den Programmzähler erhält. Wie für jeden, der einen Assembler geschrieben hat, offensichtlich ist, unterscheidet sich das Register, das den Programmzähler des Prozessors enthält, je nach Architektur. Es erscheint daher sinnvoll, für jede Architektur eine separate Implementierung zu haben. Warum wurde es also zu einem Makro vereinheitlicht?

Was ist das für ein Makro?

Zunächst konnte ich das Makro überhaupt nicht verstehen, also googelte ich es und ein sanfter älterer Bruder erklärte es mit Stapelüberlauf. Wie erwartet.

https://stackoverflow.com/questions/13902431/this-ip-macro-in-linux-kernel

Zusammenfassend,

Es scheint, dass. Es ist schwer zu verstehen, ob in Klammern () nur eine Zeile steht. Wenn Sie also einen Zeilenumbruch einfügen,

{
	__label__ __here;
__here:
	(unsigned long)&&__here;
}

Die erste Zeile ist die Deklaration des lokalen Labelnamens und die zweite Zeile ist das Label. Das lokale Label scheint in GCC verwendbar zu sein. https://gcc.gnu.org/onlinedocs/gcc-5.2.0/gcc/Local-Labels.html

Es ist eine Bezeichnung, auf die nur innerhalb eines Blocks verwiesen werden kann.

Das '&&' in der dritten Zeile ist ein spezieller Operator zur Angabe der Adresse des Etiketts (Referenz: https://docs.oracle.com/cd/E19205-01/821-0386/bjabt/index.html).

An der Position, an der dieses Makro eingebettet ist, wird __here als lokales Label in den Block eingefügt, und das Abrufen der Adresse dieses Labels ist die aktuelle Programmposition (= Programmzähler) am Ende. Da die aktuelle Position des Programms nur in C-Sprache ausgedrückt werden kann, ohne sich auf den Assembler zu verlassen, ist es daher möglich, sie auch im Kernel zu einem "THIS_IP" -Makro zu vereinheitlichen. (Außerdem sollte gcc, solange es verwendet wird, auf verschiedene Umgebungen portierbar sein, nicht auf Linux.)

Und die Beschwerde, dass ich die C-Sprache nicht verstehe

Das Problem ist darüber draußen. Ich weiß es ehrlich gesagt nicht. Normalerweise kann die Blockanweisung {} nicht als Ausdruck verwendet werden. Wenn Sie als Test den folgenden Code schreiben, wird als Test ein Kompilierungsfehler angezeigt.

int i = {1;};

Wenn Sie die block-Anweisung jedoch in Klammern () einschließen, wird sie aus irgendeinem Grund kompiliert.

int i = ({1;});

Zu diesem Zeitpunkt ist der Wert des Ausdrucks in Klammern () der Wert, wenn der am Ende der Anweisung block {} geschriebene Ausdruck ausgewertet wird. Wenn ich versuche, den folgenden Code mit gcc zu kompilieren und auszuführen, wird der Wert (= 5) des Ausdrucks d am Ende der Blockanweisung auf der Konsole angezeigt.

#include <stdio.h>
int main(void)
{
        int a = ({
                int a = 2;
                int b = 3;
                int c = 4;
                int d = 5;
                a;
                b;
                c;
                d;
        });
        printf("%d\n", a); 
        return 0;
}

Wie ist das grammatikalisch? .. ..

Wie oben erwähnt, beschäftige ich mich seit mehr als 10 Jahren mit der C-Sprache, habe sie jedoch aufgrund der Ohnmacht, die ich noch nicht kenne oder grammatikalisch nicht lese, als Memorandum zusammengefasst. ... Ich werde mein Bestes geben.

Aber ich denke ** C Sprache ist nicht schön **. Weil '&&', müssen Sie mich die ganze Zeit als Binäroperator getroffen haben ...? (Ist '&&' auch eine Erweiterung von GCC? Https://gcc.gnu.org/onlinedocs/gcc-5.2.0/gcc/Labels-as-Values.html#Labels-as-Values)

Recommended Posts

So erhalten Sie den Anweisungszeiger (= Programmzähler) im Linux-Kernel
So erhalten Sie Ergebnisse von id in Celery
So erhalten Sie Hilfe in einer interaktiven Shell
So erhalten Sie die Dateien im Ordner [Python]
So erhalten Sie den Variablennamen selbst in Python
So erhalten Sie mehrere Modellobjekte zufällig in Django
Wie man Yubico Yubikey von Manjaro Linux erkennt
So erlauben Sie Nologin-Benutzern, sich unter Linux anzumelden
[Linux] Wie Sie Ihre IP in eine Variable einfügen
So erhalten Sie RGB- und HSV-Histogramme mit OpenCV
linux / c> link> Ruft das Ausführungsergebnis des Shell-Befehls im C-Programm ab.> Mir wurde beigebracht, wie man popen () verwendet.
So schätzen Sie die Kerneldichte
So entfernen Sie benutzerdefinierte Serverpiktogramme in message.content
[Go language] So erhalten Sie Terminaleingaben in Echtzeit
Linux: Wiederherstellen, wenn 'grub_file_filters' nicht in der Grub-Rettung gefunden wurde
[Linux] [C / C ++] Zusammenfassung, wie man pid, ppid, tid bekommt
Ich habe versucht "Wie man eine Methode in Python dekoriert"
So erhalten Sie den letzten (letzten) Wert in einer Liste in Python
So erhalten Sie alle Schlüssel und Werte im Wörterbuch
So erhalten Sie eine Liste der integrierten Ausnahmen für Python
Wie man in Python entwickelt
So erhalten Sie einen Überblick über Ihre Daten in Pandas
[Shell] So erhalten Sie den Remote-Standardzweig mit Git
So starten Sie die erste Projektion
So zeigen Sie eine bestimmte Dateispalte unter Linux an (awk)
So erhalten Sie alle möglichen Werte in einem regulären Ausdruck
So bringen Sie den Druckertreiber für Oki Mac in Linux
So erhalten Sie eine Zeichenfolge aus einem Befehlszeilenargument in Python
So erhalten Sie den gesamten Datenverkehr über VPN mit OpenVPN unter Linux
So ermitteln Sie die Scheitelpunktkoordinaten eines Features in ArcPy
Holen Sie sich die der Netzwerkschnittstelle zugewiesene IPv4-Adresse in Code (Linux)
[Python] Wie man PCA mit Python macht
Verwendung von Klassen in Theano
Wie man nüchtern mit Pandas schreibt
So sammeln Sie Bilder in Python
So aktualisieren Sie Spyder in Anaconda
Verwendung von SQLite in Python
So installieren Sie VMware-Tools unter Linux
So erhalten Sie die Python-Version
So installieren Sie MBDyn (Linux Ubuntu)
So konvertieren Sie 0,5 in 1056964608 auf einmal
Wie fange ich mit Scrapy an?
Erste Schritte mit Python
[Linux] [Kernelmodul] Erstellen Sie kthread im Kernelmodul
Wie man CSS in Django reflektiert
Wie fange ich mit Django an?
Wie man Prozesse in großen Mengen abbricht
Wie man MySQL mit Python benutzt
So verpacken Sie C in Python
Verwendung von ChemSpider in Python
Verwendung von PubChem mit Python
So überprüfen Sie die Linux-Betriebssystemversion
So führen Sie TensorFlow 1.0-Code in 2.0 aus
Umgang mit Japanisch mit Python
So melden Sie sich bei Docker + NGINX an
So rufen Sie PyTorch in Julia an
So beheben Sie den Fehler "Kein Kernel der Grammatik Python gefunden" in Atom