UNIXwork

Tags

c unix dav shell linux xattr solaris links x11 java rant webdav fun gnome apple sync wtf oracle ldap network xnedit windows analytics macos benchmark curl apache bsd graalvm mac virtualbox arm zfs rhel microsoft tomcat freebsd hardware sparc

Die Ultra 45 hat 16 GB RAM, rpi4 und s920 weiß ich gerade nic

24. Dezember 2019
Raspberry Pi1 vs Raspberry Pi4 vs Fujitsu s920 vs Sun Ultra 45IOlafs aRudimenHabe noch einen Karton mit 36 x Futros Typ S920 im Keller. 4GB RAM und 8 GB SSD... ikl. Fuss und Netzteil ... Hat jemand Interesse? not a list iterator, the behavior is undefined. * If @p iter is a past-theRIIIInded to the listHabe noch einen Karton mit 36 x Futros Typ S920 im Keller. 4GB RAM und 8 GB SSD... ikl. Fuss und Netzteil ... Hat jemand Interesse?ailuXNEdit - Mein NEdit-Fork mit Unicode-SupporttBeOlaf) PeteratPerfekt, das klappt! Meine eingeschränkte Sehfähigkeit hat nämlich leider Probleme beim Fokussieren bei antialiased Text, mit dem Pixeltext geht's besser.

Damit wird Nedit durch XNedit ersetzt.
Danke! * * If @p iter is not a list iterator, the behavior is undefined. * If @p iter is a past-the-end iterator, the newPerfekt, das klappt! Meine eingeschränkte Sehfähigkeit hat nämlich leider Probleme beim Fokussieren bei antialiased Text, mit dem Pixeltext geht's besser.

Damit wird Nedit durch XNedit ersetzt.
Danke!ter() XNEdit - Mein NEdit-Fork mit Unicode-SupporttBeOlafCxIOlafor https://www.unixwork.deHallo,

Anti-Aliasing hängt von der Schriftart ab. Mit einem bitmap font sollte die Schrift klassisch wie in nedit aussehen.

Einfach unter Preferences -> Default Settings -> Text Fonts nach einer passenden Schriftart suchen.CX_EXPORT int cxListRemove(CxList *list, size_t index); /** * Removes and returns the element at the specifieHallo,

Anti-Aliasing hängt von der Schriftart ab. Mit einem bitmap font sollte die Schrift klassisch wie in nedit aussehen.

Einfach unter Preferences -> Default Settings -> Text Fonts nach einer passenden Schriftart suchen.t the lXNEdit - Mein NEdit-Fork mit Unicode-Support * Olafm tPeterufWelche Einstellung muss ich denn in der neditrc treffen, damit das Anti-Aliasing wieder abgestellt wird und ich wieder schöne scharfe, pixeltreue Schriftzeichen habe? * Removes and returns the first element of the list. * * No destructor is called, and instead the element is copied to the *Welche Einstellung muss ich denn in der neditrc treffen, damit das Anti-Aliasing wieder abgestellt wird und ich wieder schöne scharfe, pixeltreue Schriftzeichen habe?Raspberry Pi1 vs Raspberry Pi4 vs Fujitsu s920 vs Sun Ultra 45 OlafetvMettigeluccess Hallo, danke für den Vergleich. Ich beabsichtige gerade von einem Raspi auf einen HP Thinclient T630 umzusteigen. Der hat "AMD Embedded G-Series GX-420GI Radeon R7E" mit 2.0 GHz.
Ich hatte gedacht, dass der GX-415 im s920 deutlich mehr Dampf hat als der Raspi4.
Mein Thinclient verbraucht mit 16 GB RAM ~11 W idle, das ist das Dreifache vom RP4. Das muss man dem kleinen echt lassen... Sparsam ist er.
ing pointers, only the pointer is copied to @p targetbuf. * * @param list (@c CxList*) the list * @param targetbuf Hallo, danke für den Vergleich. Ich beabsichtige gerade von einem Raspi auf einen HP Thinclient T630 umzusteigen. Der hat "AMD Embedded G-Series GX-420GI Radeon R7E" mit 2.0 GHz.
Ich hatte gedacht, dass der GX-415 im s920 deutlich mehr Dampf hat als der Raspi4.
Mein Thinclient verbraucht mit 16 GB RAM ~11 W idle, das ist das Dreifache vom RP4. Das muss man dem kleinen echt lassen... Sparsam ist er.
enoughRaspberry Pi1 vs Raspberry Pi4 vs Fujitsu s920 vs Sun Ultra 45sOlafy tOlafinthttps://www.unixwork.deDie Ultra 45 hat 16 GB RAM, rpi4 und s920 weiß ich gerade nicht.

Ergebnisse von der Ultra 80 wären natürlich interessant, insbesondere im Vergleich mit dem rpi1.ist *list, void *targetbuf); /** * Removes and returns the last element of the list. * * Alias for cxListRemoveAndGetLDie Ultra 45 hat 16 GB RAM, rpi4 und s920 weiß ich gerade nicht.

Ergebnisse von der Ultra 80 wären natürlich interessant, insbesondere im Vergleich mit dem rpi1.ngHIhIxIIDatenanalyse in der Shell * @padata-analyticsLExtended AttributesaramxattrtbBlog - unixwork.defer whttp://unixwork.de/blog/ * @rettag:unixwork.de,2022:c-4al non- I8 IH I05see i,Icontent-type#detext/html; charset=utf-8etbuf) x I I I@5mult i,IstatusaOKng atpIIHTTP/1.1 200 OK Date: Mon, 18 May 2026 20:32:12 GMT Server: webserver Content-type: text/html; charset=utf-8 Transfer-encoding: chunked Connection: keep-alive her guaranteed * that the destructors are invoked for all elements before starting to remove * them, nor that the element is removed immediately after the destructor call * before proceeding to the next element. * * @param list the list * @param index the index of the element * @param num the number of elements to remove * @return the #IP#Ih#I5h IORT i,Itransfer-encodingxList chunked#I#I#I5le e i,Iconnection the keep-alivendex. * * No destructor is called, and instead the elements are copied to the * @p targetbu

Executable Memory und Intel XED

24. Dezember 2016

Ich hab mich schon öfter gefragt, was man alles tun muss, um einen JIT-Compiler zu schreiben. Oder anders gefragt, wie kann man zur Laufzeit Maschinencode generieren und ausführen.

Zunächst einmal benötigt man Speicher, der es überhaupt erlaubt, dass davon Code ausgeführt werden kann. Wenn man mit malloc Speicher alloziert, ist dieser nicht ausführbar. Intern verwendet malloc mmap und das kann auch einfach direkt genutzt werden. Dabei kann man direkt die Zugriffsrechte für den Speicher festlegen. Man könnte sie allerdings auch im nachhinein mit mprotect ändern. Mit mmap werden auch Dateien in den Speicher gemapped, durch das Flag MAP_ANONYMOUS liefert der Kernel aber ganz ohne Datei den gewünschten Speicher.

void *execmem = mmap(NULL, len, PROT_EXEC | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);

Jetzt haben wir ausführbaren Speicher. Wenn dort Instructions reingeladen werden, können diese ausgeführt werden. Mein erster Versuch war einfach mit memcpy von einem Function-Pointer dort ein paar Bytes rein zu kopieren. Das hat zwar funktioniert, auch wenn ich nicht wusste wie viele Bytes die Funktion eigentlich groß ist und ich einfach eine größere Menge kopiert habe, aber das wäre für diesen ohnehin schon etwas hackigen Blogartikel etwas zu unsauber.

Glücklicherweise hat Intel kürzlich eine Bibliothek für das decoden und encoden von x86-Maschinencode veröffentlicht. Damit ist es mir gelungen nur die Instructions der Funktion zu kopieren.

Um den Maschinencode zu decoden braucht man erstmal einen Pointer auf den Code, in meinem Fall einen Funktions-Pointer.

const xed_uint8_t *inst = (const xed_uint8_t*)func;

Einen Befehl decoden macht folgender Code:

xed_decoded_inst_t dec;
xed_error_enum_t error;

// init xed_decoded_inst_t struct
memset(&dec, '\0', sizeof(xed_decoded_inst_t));
xed_decoded_inst_set_mode(&dec, XED_MACHINE_MODE_LONG_64, XED_ADDRESS_WIDTH_64b);
    
// decode instruction
error = xed_decode(&dec, inst, 15);

Dies liest 15 Bytes (die Maximalgröße einer Instruction) und dekodiert die Instruction. Wie groß diese dann ist, kann mit xed_decoded_inst_get_length abgefragt werden. Mit der Länge kann man dann zur nächsten Instruction springen.

Man kann diese auch als Assembler-String formatieren:

// print instruction
xed_format_context(XED_SYNTAX_ATT, &dec, buffer, 1024, 0, 0, 0);
printf("%s\n", buffer);

Hier ist das fertige Beispielprogramm. Kompiliere ich das ohne Optimierung und führe es aus ist die Ausgabe:

$ ./x86dec 
copy function code:

pushq  %rbp
mov %rsp, %rbp
movl  %edi, -0x4(%rbp)
movl  %esi, -0x8(%rbp)
movl  -0x8(%rbp), %eax
movl  -0x4(%rbp), %edx
add %edx, %eax
popq  %rbp
retq  

execute new code:

f(10, 50) = 60

Das ganze erfüllt jetzt natürlich keinen Zweck. Spannend wird es erst, wenn man eigenen Code generiert und den dann ausführt.

Was man noch erwähnen sollte ist, dass CPUs separate Data- und Instruction-Caches haben. Glücklicherweise muss man sich bei x86-CPUs keine Sorgen darüber machen, da dort erkannt wird, wenn Speicher modifiziert wird, der gerade auch im Instruction-Cache ist. Hingegen bei RISC-Architekturen, z.B. ARM, muss meistens der Instruction-Cache manuell aktualisiert werden.

Siehe auch: Self-Modifying Code and the Cache on Intel x86