Page MenuHomeFreeBSD

Rewrite arm kernel stack unwind code to work when unwinding through kernel modules.
AbandonedPublic

Authored by ian on Dec 6 2019, 5:25 AM.
Tags
None
Referenced Files
Unknown Object (File)
Sun, Dec 8, 10:26 AM
Unknown Object (File)
Nov 25 2024, 1:31 AM
Unknown Object (File)
Oct 2 2024, 4:00 AM
Unknown Object (File)
Sep 26 2024, 2:09 PM
Unknown Object (File)
Sep 22 2024, 3:43 PM
Unknown Object (File)
Sep 22 2024, 8:45 AM
Unknown Object (File)
Aug 24 2024, 2:18 PM
Unknown Object (File)
Aug 24 2024, 2:14 AM
Subscribers

Details

Reviewers
None
Group Reviewers
ARM
Summary

The arm kernel stack unwinder has apparently never been able to unwind when the path of execution leads through a kernel module. There was code that tried to handle modules by looking for the unwind data in them, but it did so by trying to find symbols which have never existed in arm kernel modules. That caused the unwind code to panic, and because part of panic handling calls into the unwind code, that just created a recursion loop.

Locating the unwind data in a loaded module requires accessing the Elf section headers to find the SHT_ARM_EXIDX section. For preloaded modules those headers are present in a metadata blob. For dynamically loaded modules, the headers are present only while the loading is in progress; the memory is freed once the module is ready to use. For that reason, there is new code in kern/link_elf.c, wrapped in #ifdef arm, to extract the unwind info while the headers are loaded. The values are saved into new fields in the linker_file structure which are also conditional on arm.

In arm/unwind.c there is new code to locally cache the per-module info needed to find the unwind tables. The local cache is crafted for lockless read access, because the unwind code often needs to run in context where sleeping is not allow. A large comment block describes the local cache list, so I won't repeat it all here.

Test Plan

Tested by calling panic() from a loaded module, and getting a backtrace in kdb without the recursion loop that existing code triggers.

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Skipped
Unit
Tests Skipped
Build Status
Buildable 27998