GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Wie können Sie das VDSO-Objekt mit Ihrer eigenen Programmiersprache nutzen?

Es hängt davon ab, ob Ihre Implementierung C verwendet Schnittstelle für Low-Level-Dienstprogramme oder nicht.

Wenn Ihre Sprachimplementierung direkten Zugriff auf Systemaufrufe gewährt, ohne über C zu gehen Wrapper müssen Sie VDSO nicht verwenden (Sie könnten beispielsweise den entsprechenden SYSENTER generieren Maschinenanweisung, um den Syscall auszuführen), aber Sie könnten sich entscheiden, VDSO zu verwenden und es dann zu nutzen. In diesem Fall muss Ihre Sprache nicht einmal alle ABI-Konventionen befolgen, sondern nur die Konventionen des Kernels. (Zum Beispiel benötigen Sie nicht die von ABI bereitgestellte caller-safe calle-safe distinguo auf Registern, und Sie könnten sogar die Verwendung von Stacks vermeiden).

Ein Beispiel für eine Sprachimplementierung, die nicht einmal libc.so verwendet ist Bones Scheme. Du könntest noch ein paar andere finden.

Mein Verständnis des VDSO ist, dass es eine vom Kernel bereitgestellte Abstraktion ist, um die verschiedenen kleinen Unterschiede (im Zusammenhang mit Benutzerland -> Kernel-Übergängen) bei der Implementierung von Systemaufrufen zwischen verschiedenen Familien von x86-Prozessoren zu abstrahieren. Wenn Sie sich für ein bestimmtes Prozessorziel entschieden haben, benötigen Sie VDSO nicht und können es jederzeit vermeiden.

AFAIU, das VDSO ist ein gemeinsames ELF-Objekt, das (auf meinem Debian/AMD64 mit einem kürzlich kompilierten 3.8.3-Kernel) im Segment ffffffffff600000-ffffffffff601000 sitzt; genau prüfen mit cat /proc/self/maps wo ist es). Sie müssen also nur die Organisation von gemeinsam genutzten ELF-Objekten verstehen und die Symbole daraus abrufen. Siehe dies-und-das-Links. Der VDSO verwendet die C-Konventionen zum Aufrufen, die in der x86-64-ABI-Spezifikation dokumentiert sind.

ELF ist ein gut dokumentiertes Format. Und das gilt auch für die x86-64-ABI-Konventionen (die genau die C-Aufrufkonventionen definieren und wie genau das Image eines Prozesses beginnt. Siehe auch die Manpage execve(2)) und natürlich die Kernel-Dokumentation, also verstehe ich das nicht Was ist dein Problem. Ich stimme zu, dass es Zeit braucht, ELF zu verstehen (ich habe das vor 10 Jahren gemacht, aber mein Gedächtnis ist eingerostet). Lesen Sie auch <elf.h> Header-Datei auf Ihrem Rechner.

Zum Beispiel; läuft (unter zsh auf 64-Bit-Debian x86-64)

 % file $(which sash)
 /bin/sash: ELF 64-bit LSB executable, x86-64, version 1 (SYSV),
      statically linked, for GNU/Linux 2.6.26,
      BuildID[sha1]=0x0347fcc08fba2f811f58af99f26111d0f579a9f6, stripped

 % ldd $(which sash)
 not a dynamic executable

  % sash
  Stand-alone shell (version 3.7)
  > ps |grep sash
  21635 pts/3    00:00:00 sash
  > cat /proc/21635/maps
  00400000-004da000 r-xp 00000000 08:01 4985590                            /bin/sash
  006da000-006dc000 rw-p 000da000 08:01 4985590                            /bin/sash
  006dc000-006e1000 rw-p 00000000 00:00 0 
  017e3000-01806000 rw-p 00000000 00:00 0                                  [heap]
  7fe4950e5000-7fe4950e7000 rw-p 00000000 00:00 0 
  7fff3f130000-7fff3f151000 rw-p 00000000 00:00 0                          [stack]
  7fff3f173000-7fff3f175000 r-xp 00000000 00:00 0                          [vdso]
  ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

Siehe auch diese Antwort.

Sie möchten wahrscheinlich in Ihrer Laufzeit eine minimale Version eines dynamischen Linkers, der in der Lage ist, das VDSO einfach zu analysieren. Sie möchten sicherlich den genauen Zustand verstehen, in dem ein Prozess gestartet wird, und insbesondere die Rolle von auxv , der Hilfsvektor (ich habe diese Details wirklich vergessen, aber ich erinnere mich, dass sie wichtig sind). Siehe z.B. diesen Artikel

Tatsächlich ist das zuverlässige Starten Ihrer Laufzeit wahrscheinlich schwieriger als das VDSO-Problem.

Vielleicht möchten Sie auch das Linux-Assembler-Howto lesen, das auch einige Dinge erklärt (aber mehr über x86 als über x86-64)

Übrigens, der Code von http://musl-libc.org/ (das eine alternative libc ist) ist viel einfacher zu lesen und zu verstehen (und Sie werden leicht lernen, wie sie dynamisches Linken, Pthreads usw. machen.)


Ich fand diese Dateien im Linux-Kernelbaum hilfreich:

  • Documentation/ABI/stable/vdso (Was ist das vDSO-Objekt?)
  • Documentation/vDSO/parse_vdso.c (Referenzparser für das vDSO-Objekt)

Das vDSO-Objekt ist ein virtuelles dynamisches gemeinsam genutztes Objekt, das unter Linux immer in den Adressraum eines amd64-Prozesses abgebildet wird. Es kann verwendet werden, um schnelle Systemaufrufe zu implementieren. Um auf die Funktionen innerhalb des vDSO-Objekts zuzugreifen, müssen Sie

  • Suche das Objekt
  • eine Adresse aus der Symboltabelle extrahieren

Beides lässt sich mit der CC0-lizenzierten Referenzimplementierung parse_vdso.c erledigen.


Linux
  1. So erweitern Sie die Funktionalität Ihres Linux-Desktops mit PlexyDesk

  2. So fangen Sie an, eine Programmiersprache zu lernen

  3. Wie installiere ich R 3.3.1 im eigenen Verzeichnis?

  4. Wie ändere ich die Sprache Ihres cPanels?

  5. Wie Sie Ihre Ubuntu-Linux-Server mit der Phoronix Test Suite benchmarken

So finden Sie den Standort Ihrer Server mit Traceroute und WHOIS

Gewusst wie:Einführung in die Programmierung – Objektorientierte Programmierung

So installieren Sie die Go-Programmiersprache unter Ubuntu 20.04

So installieren Sie die Programmiersprache Rust auf AlmaLinux 8

So installieren Sie die Programmiersprache Rust unter Linux

So installieren Sie GoLang (Go-Programmiersprache) unter Linux