#!/usr/bin/env bash set -euo pipefail root="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)" nm_tool="${RISCV_PREFIX:-riscv64-unknown-elf-}nm" readelf_tool="${RISCV_PREFIX:-riscv64-unknown-elf-}readelf" symbol_value() { "$nm_tool" -n "$1" | awk -v wanted="$2" '$3 == wanted { print $1; exit }' } for task in \ task01_libc_without_heap \ task03_bounded_sbrk \ task04_smalloc \ task05_picolibc_malloc; do elf="$root/build/$task/prog.elf" start_hex="$(symbol_value "$elf" __heap_start)" end_hex="$(symbol_value "$elf" __heap_end)" stack_bottom_hex="$(symbol_value "$elf" __stack_bottom)" reset_hex="$(symbol_value "$elf" .reset_handler)" [[ -n "$start_hex" && -n "$end_hex" && -n "$stack_bottom_hex" ]] [[ "$reset_hex" == "80000040" ]] (( 16#$start_hex <= 16#$end_hex )) (( 16#$end_hex == 16#$stack_bottom_hex )) (( (16#$start_hex & 15) == 0 )) (( (16#$end_hex & 15) == 0 )) "$readelf_tool" -h "$elf" | grep -q 'Class:.*ELF32' if "$readelf_tool" -lW "$elf" | grep -Eq 'LOAD.*RWE'; then echo "FAIL $task: writable and executable LOAD segment" >&2 exit 1 fi done task05="$root/build/task05_picolibc_malloc/prog.elf" for symbol in _sbrk sbrk malloc free __heap_start __heap_end; do [[ -n "$(symbol_value "$task05" "$symbol")" ]] done printf '%s\n' \ 'PASS linker: reset=0x80000040; bounded aligned heap; no RWX LOAD segment' \ 'PASS Task05 ELF: vendor _sbrk and picolibc sbrk coexist'