C09 — smalloc, sbrk i minimalne libc
Pięć krótkich eksperymentów rozdziela trzy warstwy, które łatwo pomylić:
funkcję biblioteczną niewymagającą sterty, kontrakt malloc → sbrk oraz
politykę prostego alokatora przyrostowego. Karta używa rzeczywistego toolchaina
GCC 15.2 z picolibc dla RV32I/Hazard3.
Przykłady
| Task | Pytanie rozstrzygane przez program | Wynik |
|---|---|---|
| 01 | Czy każda funkcja libc wymaga sterty? | strlen.c.o trafia do mapy, człony malloc/sbrk nie. |
| 02 | Co się stanie bez dostawcy sbrk? |
Kontrolowany błąd linkera: brak __wrap_sbrk. |
| 03 | Jaki jest minimalny bezpieczny kontrakt przesuwania break? | heap_start <= brk <= heap_end; błąd nie przesuwa break. |
| 04 | Co naprawdę gwarantuje smalloc? |
Nagłówek przed payloadem, 16 B alignment, append-only, tylko reset całej areny. |
| 05 | Jak zachowuje się prawdziwe malloc/free picolibc? |
Dwa rozłączne bloki, zapis/odczyt, free; implementacja pozostaje czarną skrzynką. |
Każdy przykład na karcie ma dokładnie widoki A1–A8. A3 jest oznaczony
N/D, bo w żadnym przykładzie nie ma callbacku, ISR ani dynamicznego wyboru
wykonawcy. Task02 nie ma A6 runtime, ponieważ zgodnie z celem nie powstaje ELF.
Ważne nazwy symboli
vendor/Hazard3/test/sim/common/init.S definiuje _sbrk z podkreśleniem.
Picolibc w tym toolchainie definiuje i wywołuje sbrk bez podkreślenia.
Są to różne symbole; Task05 celowo zachowuje oba w jednym ELF-ie. Task03 i
Task04 używają nazwy c09_sbrk, aby nie podszywać się pod libc.
Własny skrypt link/hazard3_c09.ld udostępnia picolibc symbole
__heap_start i __heap_end, rezerwuje 64 KiB na stos przy końcu 16 MiB RAM
i zatrzymuje linkowanie przez ASSERT, jeżeli sterta nachodzi na stos.
Budowanie i dowody
make host-test
make expected-fail
make tasks archive-map check-elf
make hazard3-test
make card-check
make task2 ma zakończyć się sukcesem jako test, ale zapisany w logu link
programu ma zakończyć się porażką. Nie jest to zepsuty build: flaga
--wrap=sbrk przekierowuje odwołanie picolibc na celowo niezdefiniowany
__wrap_sbrk, dzięki czemu zależność jest dowodzona deterministycznie.
Udane obrazy RV32I znajdują się w build/<task>/ jako ELF, BIN, listing i
mapa linkera. Task02 ma tylko obiekt, mapę częściowego linku i
expected-link-failure.log; plik must-not-exist.elf jest zabroniony przez
test.
Zakres modelu smalloc
c09_smalloc jest celowo mały: wyrównuje całkowity blok do 16 B, zapisuje
16-bajtowy nagłówek bezpośrednio przed payloadem i dopisuje kolejny blok na
końcu. Nie ma c09_sfree, listy wolnych bloków, split ani coalescing.
c09_smalloc_reset unieważnia całą arenę naraz i służy tylko do kontrolowanego
ćwiczenia. Task05 nie wyciąga z tego modelu wniosków o wnętrzu picolibc.