Blog
Implementierungshinweise zum Allokator
2023-06-28
Sonderfall map(nullptr)
In der Aufgabenstellung
wird der map
-Systemaufruf zusammen mit dem Allokator für
den Userspace als Beispiel gezeigt. Der Allokator verwendet intern
(versteckt hinter einer Templatevariable) beim ersten Aufruf
map(nullptr, ...)
, lässt sich also vom Kernel eine Adresse
geben. Und fordert bei Bedarf dann weiteren Speicher an – braucht aber
unbedingt einen zusammenhängenden Speicherbereich (und verwendet deshalb
in den folgenden map
-Aufrufen auch explizite Adressen).
Das bedeutet unter Umständen, dass ihr, wenn ihr den Allokator so wie
in der Vorgabe verwendet, aber auch noch zusätzlich in eurer Anwendung
map(nullptr, ...)
aufrufen wollt, der Allokator keinen
weiteren Speicher mehr rausgeben wird.
Mögliche Workarounds:
entweder einfach
map
mit expliziten Zieladressen (jenseits von0x5000000
[Userspace + App + Allokator]) in eurer Anwendung aufrufenoder
alloc_buddy.h
im Userspace (jedoch nicht im Kernel) patchen, zum Beispiel den Code in Zeile 355if ((base_ptr = reinterpret_cast<uintptr_t>(RESERVE(nullptr, size))) == NULL) { return NULL; }
zu etwas wie
if ((base_ptr = reinterpret_cast<uintptr_t>(RESERVE(reinterpret_cast<void*>(0x1000000000), size))) == NULL) { return NULL; }
zu ändern, um den Heap ab
0x1000000000
starten zu lassen.oder beim Aufruf mit Parameter
nullptr
schlicht ganz zufällige (noch unbelegte) Adressen rauszugeben. Grundlegende Idee:void* map(void* addr, size_t size) { if (addr == nullptr) { static uintptr_t nextPtr = 88172645463325252ull; // TODO: Eigener Wert do { ^= nextPtr << 13; nextPtr ^= nextPtr >> 7; nextPtr ^= nextPtr << 17; nextPtr = reinterpret_cast<void*>(nextPtr); addr } while (addr < USER_SPACE || mapping->in_use(addr, size)); } // ... }