feat: add lab-rv32i-c-smalloc-sbrk-libc card

This commit is contained in:
user
2026-07-21 19:14:20 +02:00
commit d522c15f75
33 changed files with 5965 additions and 0 deletions
+59
View File
@@ -0,0 +1,59 @@
# 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 A1A8. 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/<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.