# 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 ```bash 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//` 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.