diff options
author | Jason Molenda <jmolenda@apple.com> | 2025-10-07 16:52:47 -0700 |
---|---|---|
committer | Jason Molenda <jmolenda@apple.com> | 2025-10-07 17:03:17 -0700 |
commit | 01a8f9b81870ac9bfe26d80fa3313d56cb8cbe13 (patch) | |
tree | c75ead75d28019d2d6d28285149af78d6e402a9f /clang/lib/CodeGen/CodeGenModule.cpp | |
parent | b7df53380960efca085e3d849d3a163e8e919880 (diff) | |
download | llvm-01a8f9b81870ac9bfe26d80fa3313d56cb8cbe13.zip llvm-01a8f9b81870ac9bfe26d80fa3313d56cb8cbe13.tar.gz llvm-01a8f9b81870ac9bfe26d80fa3313d56cb8cbe13.tar.bz2 |
[lldb] Cortex-M exception unwind API test cleanup
This test, with a corefile created via yaml2macho-core plus an
ObjectFileJSON binary with symbol addresses and ranges, was failing
on some machines/CI because the wrong ABI was being picked.
The bytes of the functions were not included in the yaml or .json
binary. The unwind falls back to using the ABI plugin default
unwind plans. We have two armv7 ABIs - the Darwin ABI that always
uses r7 as the frame pointer, and the AAPCS ABI which uses r11 code.
In reality, armv7 code uses r11 in arm mode, r7 in thumb code. But
the ABI ArchDefaultUnwindPlan doesn't have any access to the Target's
ArchSpec or Process register state, to determine the correct processor
state (arm or thumb). And in fact, on Cortex-M targets, the
instructions are always thumb, so the arch default unwind plan
(hardcoded r11) is always wrong.
The corefile doesn't specify a vendor/os, only a cpu.
The object file json specifies the armv7m-apple-* triple, which will
select the correct ABI plugin, and the test runs.
In some cases, it looks like the Process ABI was fetched after
opening the corefile, but before the binary.json was loaded and
corrected the Target's ArchSpec. And we never re-evaluate the ABI
once it is set, in a Process. When we picked the AAPCS armv7 ABI,
we would try to use r11 as frame pointer, and the unwind would stop
after one stack frame.
I'm stepping around this problem by (1) adding the register bytes of
the prologues of every test function in the backtrace, and (2)
shortening the function ranges (in binary.json) to specify that the
functions are all just long enough for the prologue where execution
is stopped. The instruction emulation plugin will fail if it can't
get all of the bytes from the function instructions, so I hacked
the function sizes in the .json to cover the prologue plus one and
changed the addresses in the backtrace to fit within those ranges.
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
0 files changed, 0 insertions, 0 deletions