This is an archive of the discontinued LLVM Phabricator instance.

[libunwind][AArch64] Add support for DWARF expression for RA_SIGN_STATE.
ClosedPublic

Authored by danielkiss on Apr 13 2022, 10:28 AM.

Details

Summary

Program may set the RA_SIGN_STATE pseudo register by expressions.
Libunwind expected only the DW_CFA_AARCH64_negate_ra_state could change the value
of the register which leads to runtime errors on PAC enabled systems.
In the recent version of the aadwarf64[1] a limitation is added[2] to forbid the mixing the
DW_CFA_AARCH64_negate_ra_state with other DWARF Register Rule Instructions.

[1] https://github.com/ARM-software/abi-aa/releases/tag/2022Q1
[2] https://github.com/ARM-software/abi-aa/pull/129

Diff Detail

Event Timeline

danielkiss created this revision.Apr 13 2022, 10:28 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 13 2022, 10:28 AM
danielkiss requested review of this revision.Apr 13 2022, 10:28 AM
MaskRay accepted this revision.May 4 2022, 10:52 AM

I only have basic understanding of PAC, but I tried reading through and the implementation looks good.

libunwind/src/DwarfInstructions.hpp
177

Perhaps raSignState to stick with the variable naming convention.

179

I assume that both branches are tested.

libunwind/test/aarch64.ra_sign_state.pass.cpp
16

Prefer () for C++.

22

Reword the comment to describe what foo tests first.

23

dwarf => DWARF

25

Space after //

29

add sp, sp, 16 has an assumption that sp cannot be used as the CFA. I presume that this is always guaranteed because fp/lr are always stored together(?) and therefore fp is the CFA.

41

Test that .cfi_negate_ra_state emitted by the compiler can be handled.

This revision is now accepted and ready to land.May 4 2022, 10:52 AM
danielkiss updated this revision to Diff 427241.May 5 2022, 2:06 AM
danielkiss marked 6 inline comments as done.

@MaskRay thanks so much.

libunwind/src/DwarfInstructions.hpp
179

correct, the test unwind a function with ".cfi_negate_ra_state" and in this case the register location is 'unused'.

libunwind/test/aarch64.ra_sign_state.pass.cpp
29

"add sp, sp, 16\n" assumes only the stack alignment https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst#6221universal-stack-constraints.

FP might not saved ( I'll change the restore line ) but the frame will be adjusted always by 16bytes.

41

unwinder will walk back to main therefore it will see the .cfi_negate_ra_state because it is enforced by branch-protection=pac-ret attribute.

MaskRay accepted this revision.May 12 2022, 4:35 PM
This revision was landed with ongoing or failed builds.May 13 2022, 1:06 AM
This revision was automatically updated to reflect the committed changes.
Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptMay 13 2022, 1:06 AM

Hi @danielkiss,

the FAIL: llvm-libunwind-static.cfg.in:: aarch64.ra_sign_state.pass.cpp test is getting failed on Linux Ubuntu/Aarch64 toolchain builders with the following output:

terminate called after throwing an instance of 'int'
terminate called recursively

here is more details: https://lab.llvm.org/buildbot/#/builders/119/builds/8501/steps/12/logs/FAIL__llvm-libunwind-static_cfg_in___aarch64_ra_si

https://lab.llvm.org/buildbot/#/builders/119/builds/8501

Hi @danielkiss,

the FAIL: llvm-libunwind-static.cfg.in:: aarch64.ra_sign_state.pass.cpp test is getting failed on Linux Ubuntu/Aarch64 toolchain builders with the following output:

terminate called after throwing an instance of 'int'
terminate called recursively

here is more details: https://lab.llvm.org/buildbot/#/builders/119/builds/8501/steps/12/logs/FAIL__llvm-libunwind-static_cfg_in___aarch64_ra_si

https://lab.llvm.org/buildbot/#/builders/119/builds/8501

Sorry for that, reverted until I can reproduces it locally, I will do this this coming week.

Mordante added inline comments.
libunwind/src/DwarfInstructions.hpp
180

In the libc++ pre-commit CI I see some failures https://buildkite.com/llvm-project/libcxx-ci/builds/10887#fb4448a3-a3f7-4a0a-8997-ccbdfd1b35a3

/home/tcwg-buildbot/worker/linaro-aarch64-libcxx-01/llvm-project/libcxx-ci/libunwind/src/DwarfInstructions.hpp:180:26: error: implicit conversion changes signedness: 'int64_t' (aka 'long') to 'libunwind::DwarfInstructions<libunwind::LocalAddressSpace, libunwind::Registers_arm64>::pint_t' (aka 'unsigned long') [-Werror,-Wsign-conversion]
    raSignState = regloc.value;

I didn't verify this patch caused it, but it seems very likely to me.

danielkiss marked an inline comment as done.May 19 2022, 12:44 AM
danielkiss added inline comments.
libunwind/src/DwarfInstructions.hpp
180

Yes, it did. Revert reverted this too, so it is relanded.
https://github.com/llvm/llvm-project/commit/6716e2055ddeac304f47adc5ae39086381016ba7

c218fd3d7d3764eb123c8429bbcd33bacfe2e633 added libcxxabi/test/native/AArch64/ra_sign_state.pass.cpp -- was that intended, or should it have been added to libunwind/test/[...]? It also started failing in the CI in the -fno-exceptions configuration -- I think it is just missing a XFAIL so I'll add it, but please investigate whether the file needs to be moved (I think it does). If so, please make sure to open a code review for that change since it will cause our pre-commit CI to run, and please don't commit the change until it is green :-).

danielkiss marked an inline comment as done.May 20 2022, 7:11 AM

c218fd3d7d3764eb123c8429bbcd33bacfe2e633 added libcxxabi/test/native/AArch64/ra_sign_state.pass.cpp -- was that intended, or should it have been added to libunwind/test/[...]? It also started failing in the CI in the -fno-exceptions configuration -- I think it is just missing a XFAIL so I'll add it, but please investigate whether the file needs to be moved (I think it does).

Tests in libunwind can't depend on libcxx (failed in llvm-libunwind-static.cfg.in) so the test is moved to libcxxabi, because test test case needs exception. (simple backtrace won't trigger the problem)

If so, please make sure to open a code review for that change since it will cause our pre-commit CI to run, and please don't commit the change until it is green :-).

Sure will do.