05-addr2line-linked.sh (1877B)
1 # Golden: debug-info retention through the linker (IMAGE_INSPECT phase 5). 2 # Links two `-g` objects into a static aarch64 ELF executable, then asserts 3 # `kit addr2line` resolves file:line for a function from *each* input — 4 # exercising multi-input .debug_* concatenation, per-input SK_SECTION 5 # rebasing, and the .debug_aranges debug_info_offset reloc. Also confirms 6 # the merged image carries a single .debug_info/.debug_line and that 7 # `ld -S` drops debug entirely. Built fresh (not a committed binary) so the 8 # file:line mapping tracks the C front-end + debug emitter. 9 set -e 10 CC="cc -g -c -target aarch64-linux" 11 12 cat > a.c <<'EOF' 13 extern int compute(int); 14 int helper(int x) { return x * 3; } 15 void _start(void) { compute(5); } 16 EOF 17 cat > b.c <<'EOF' 18 extern int helper(int); 19 int compute(int n) { 20 int acc = 0; 21 for (int i = 0; i < n; i++) acc += helper(i); 22 return acc; 23 } 24 int main(void) { return compute(5); } 25 EOF 26 27 $KIT $CC -o a.o a.c 28 $KIT $CC -o b.o b.c 29 $KIT ld -o prog.elf a.o b.o -e _start 30 31 # Merged debug sections: one .debug_info / .debug_line spanning both inputs. 32 echo "merged debug sections:" 33 $KIT objdump -h prog.elf | awk '$2 ~ /^\.debug_(info|line)$/ {print " " $2}' | sort 34 35 # addr2line resolves a function defined in each input (helper/_start from 36 # a.c, compute/main from b.c) — wrong rebasing would map them all to one CU. 37 echo "addr2line:" 38 for fn in _start helper compute main; do 39 addr=$($KIT nm prog.elf | awk -v f=" $fn\$" '$0 ~ f {print $1}') 40 printf ' %-8s %s\n' "$fn" "$($KIT addr2line -e prog.elf "0x$addr")" 41 done 42 43 # -S strips debug: no .debug_* shdrs, addr2line reports no info. 44 $KIT ld -S -o stripped.elf a.o b.o -e _start 45 echo "stripped debug shdrs: $($KIT objdump -h stripped.elf | grep -c '\.debug_')" 46 caddr=$($KIT nm stripped.elf | awk '/ compute$/{print $1}') 47 echo "stripped addr2line: $($KIT addr2line -e stripped.elf "0x$caddr" 2>&1)"