Skip to content

[PAuth] Fix lowering of ptrauth constants with big offsets #79

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
kovdan01 opened this issue Jun 10, 2024 · 3 comments
Closed

[PAuth] Fix lowering of ptrauth constants with big offsets #79

kovdan01 opened this issue Jun 10, 2024 · 3 comments
Assignees
Labels

Comments

@kovdan01
Copy link
Contributor

kovdan01 commented Jun 10, 2024

Consider the following IR:

@g = external global i32  
define ptr @test_global_big_offset_zero_disc() {  
  ret ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 add (i64 2147483648, i64 65537)), i32 2)   
}

When compiling to an object file via the following command:

llc -mtriple aarch64-elf -mattr=+pauth -filetype=obj test.ll

We get the following assertion triggered:

llc: /path/to/llvm-project/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp:290: uint32_t {anonymous}::AArch64MCCodeEmitter::getAddSubImmOpValue(const llvm::MCInst&, unsigned int, llvm::SmallVectorImpl<llvm::MCFixup>&, const llvm::MCSubtargetInfo&) const: Assertion `(ShiftVal == 0 || ShiftVal == 12) && "unexpected shift value for add/sub immediate"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.	Program arguments: ./.build/rel-with-deb-info/bin/llc -mtriple aarch64-elf -mattr=+pauth -filetype=obj /path/to/test.ll
1.	Running pass 'Function Pass Manager' on module '/path/to/test.ll'.
2.	Running pass 'AArch64 Assembly Printer' on function '@test_global_big_offset_zero_disc'
 #0 0x000065856e30ee1c llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /path/to/llvm-project/llvm/lib/Support/Unix/Signals.inc:727:3
 #1 0x000065856e30bf44 llvm::sys::RunSignalHandlers() /path/to/llvm-project/llvm/lib/Support/Signals.cpp:105:20
 #2 0x000065856e30d445 SignalHandler(int) /path/to/llvm-project/llvm/lib/Support/Unix/Signals.inc:403:31
 #3 0x000065856ee50ae0 (/usr/lib/libc.so.6+0x3cae0)
 #4 0x000065856eea8e44 (/usr/lib/libc.so.6+0x94e44)
 #5 0x000065856ee50a30 raise (/usr/lib/libc.so.6+0x3ca30)
 #6 0x000065856ee384c3 abort (/usr/lib/libc.so.6+0x244c3)
 #7 0x000065856ee383df (/usr/lib/libc.so.6+0x243df)
 #8 0x000065856ee48c67 (/usr/lib/libc.so.6+0x34c67)
 #9 0x0000658572863ae0 (anonymous namespace)::AArch64MCCodeEmitter::getAddSubImmOpValue(llvm::MCInst const&, unsigned int, llvm::SmallVectorImpl<llvm::MCFixup>&, llvm::MCSubtargetInfo const&) const (.constprop.0) /path/to/llvm-project/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp:313:1
#10 0x000065857286a73f (anonymous namespace)::AArch64MCCodeEmitter::getBinaryCodeForInstr(llvm::MCInst const&, llvm::SmallVectorImpl<llvm::MCFixup>&, llvm::MCSubtargetInfo const&) const (.isra.0) /path/to/llvm-project/.build/rel-with-deb-info/lib/Target/AArch64/AArch64GenMCCodeEmitter.inc:12694:10
#11 0x000065857287e29a llvm::SmallVectorBase<unsigned long>::size() const /path/to/llvm-project/llvm/include/llvm/ADT/SmallVector.h:91:32
#12 0x000065857287e29a llvm::SmallVectorTemplateCommon<char, void>::assertSafeToAdd(void const*, unsigned long) /path/to/llvm-project/llvm/include/llvm/ADT/SmallVector.h:210:59
#13 0x000065857287e29a llvm::SmallVectorTemplateCommon<char, void>::assertSafeToAddRange(char const*, char const*) /path/to/llvm-project/llvm/include/llvm/ADT/SmallVector.h:230:26
#14 0x000065857287e29a llvm::SmallVectorTemplateCommon<char, void>::assertSafeToAddRange(char const*, char const*) /path/to/llvm-project/llvm/include/llvm/ADT/SmallVector.h:227:8
#15 0x000065857287e29a void llvm::SmallVectorImpl<char>::append<char const*, void>(char const*, char const*) /path/to/llvm-project/llvm/include/llvm/ADT/SmallVector.h:697:31
#16 0x000065857287e29a void llvm::support::endian::write<unsigned int>(llvm::SmallVectorImpl<char>&, unsigned int, llvm::endianness) /path/to/llvm-project/llvm/include/llvm/Support/EndianStream.h:63:13
#17 0x000065857287e29a (anonymous namespace)::AArch64MCCodeEmitter::encodeInstruction(llvm::MCInst const&, llvm::SmallVectorImpl<char>&, llvm::SmallVectorImpl<llvm::MCFixup>&, llvm::MCSubtargetInfo const&) const /path/to/llvm-project/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp:717:35
#18 0x000065856ed33536 llvm::SmallVectorBase<unsigned int>::size() const /path/to/llvm-project/llvm/include/llvm/ADT/SmallVector.h:91:32
#19 0x000065856ed33536 llvm::SmallVectorTemplateCommon<llvm::MCFixup, void>::end() /path/to/llvm-project/llvm/include/llvm/ADT/SmallVector.h:282:41
#20 0x000065856ed33536 llvm::MCELFStreamer::emitInstToData(llvm::MCInst const&, llvm::MCSubtargetInfo const&) /path/to/llvm-project/llvm/lib/MC/MCELFStreamer.cpp:556:22
#21 0x000065856ed5810c std::__uniq_ptr_impl<llvm::MCAssembler, std::default_delete<llvm::MCAssembler>>::_M_ptr() const /usr/include/c++/14.1.1/bits/unique_ptr.h:193:67
#22 0x000065856ed5810c std::unique_ptr<llvm::MCAssembler, std::default_delete<llvm::MCAssembler>>::get() const /usr/include/c++/14.1.1/bits/unique_ptr.h:464:27
#23 0x000065856ed5810c std::unique_ptr<llvm::MCAssembler, std::default_delete<llvm::MCAssembler>>::operator*() const /usr/include/c++/14.1.1/bits/unique_ptr.h:447:2
#24 0x000065856ed5810c llvm::MCObjectStreamer::getAssembler() /path/to/llvm-project/llvm/include/llvm/MC/MCObjectStreamer.h:128:41
#25 0x000065856ed5810c llvm::MCObjectStreamer::emitInstruction(llvm::MCInst const&, llvm::MCSubtargetInfo const&) /path/to/llvm-project/llvm/lib/MC/MCObjectStreamer.cpp:429:15
#26 0x0000658573397edb llvm::SmallVectorTemplateCommon<llvm::MCOperand, void>::isSmall() const /path/to/llvm-project/llvm/include/llvm/ADT/SmallVector.h:156:39
#27 0x0000658573397edb llvm::SmallVectorImpl<llvm::MCOperand>::~SmallVectorImpl() /path/to/llvm-project/llvm/include/llvm/ADT/SmallVector.h:616:23
#28 0x0000658573397edb llvm::SmallVector<llvm::MCOperand, 6u>::~SmallVector() /path/to/llvm-project/llvm/include/llvm/ADT/SmallVector.h:1216:3
#29 0x0000658573397edb llvm::MCInst::~MCInst() /path/to/llvm-project/llvm/include/llvm/MC/MCInst.h:184:7
#30 0x0000658573397edb llvm::MCInstBuilder::~MCInstBuilder() /path/to/llvm-project/llvm/include/llvm/MC/MCInstBuilder.h:21:0
#31 0x0000658573397edb LowerMOVaddrPAC /path/to/llvm-project/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp:1708:0
#32 0x0000658573397edb (anonymous namespace)::AArch64AsmPrinter::emitInstruction(llvm::MachineInstr const*) /path/to/llvm-project/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp:1941:0
#33 0x000065857231f3ff llvm::AsmPrinter::emitFunctionBody() /path/to/llvm-project/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp:1856:9
#34 0x000065857338972b (anonymous namespace)::AArch64AsmPrinter::runOnMachineFunction(llvm::MachineFunction&) /path/to/llvm-project/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp:180:0
#35 0x00006585712143b8 llvm::MachineFunctionPass::runOnFunction(llvm::Function&) (.part.0) /path/to/llvm-project/llvm/lib/CodeGen/MachineFunctionPass.cpp:93:33
#36 0x000065856e92ea35 llvm::FPPassManager::runOnFunction(llvm::Function&) /path/to/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:1441:40
#37 0x000065856e92eca1 llvm::ilist_node_base<true>::getNext() const /path/to/llvm-project/llvm/include/llvm/ADT/ilist_node_base.h:43:45
#38 0x000065856e92eca1 llvm::ilist_node_impl<llvm::ilist_detail::node_options<llvm::Function, true, false, void, false>>::getNext() /path/to/llvm-project/llvm/include/llvm/ADT/ilist_node.h:94:66
#39 0x000065856e92eca1 llvm::ilist_iterator<llvm::ilist_detail::node_options<llvm::Function, true, false, void, false>, false, false>::operator++() /path/to/llvm-project/llvm/include/llvm/ADT/ilist_iterator.h:157:25
#40 0x000065856e92eca1 llvm::FPPassManager::runOnModule(llvm::Module&) /path/to/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:1486:22
#41 0x000065856e92fd26 runOnModule /path/to/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:1556:38
#42 0x000065856e92fd26 llvm::legacy::PassManagerImpl::run(llvm::Module&) /path/to/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:541:55
#43 0x00000bff11c4305f compileModule(char**, llvm::LLVMContext&) /path/to/llvm-project/llvm/tools/llc/llc.cpp:742:34
#44 0x00000bff11c444b7 main /path/to/llvm-project/llvm/tools/llc/llc.cpp:409:35
#45 0x000065856ee39c88 (/usr/lib/libc.so.6+0x25c88)
#46 0x000065856ee39d4c __libc_start_main (/usr/lib/libc.so.6+0x25d4c)
#47 0x00000bff11c33f95 _start (./.build/rel-with-deb-info/bin/llc+0x16f95)

We try to emit "add immediate" instruction with 24-bit shift of the immediate while only 0 or 12 bits are allowed. See https://developer.arm.com/documentation/ddi0602/2023-09/Base-Instructions/ADD--immediate---Add--immediate--?lang=en.

According to comments in code, it's intended to support offsets as wide as 32-bit unsigned integers. Doing that with just add operation with a shift is not feasible since 24-bit shifts are not allowed.

For wide offsets, we should use a temporary register for storing the immediate and a sequence from movz/movk/movn instructions to fill this register.

@kovdan01 kovdan01 self-assigned this Jun 10, 2024
@kovdan01 kovdan01 added the pauth label Jun 10, 2024
@asl
Copy link
Contributor

asl commented Jun 12, 2024

Tagging @ahmedbougacha

The issue does exist regardless of the platform (ELF vs MachO)

@kovdan01
Copy link
Contributor Author

With latest changes in llvm/llvm-project#94241, the issue should be resolved.

@kovdan01
Copy link
Contributor Author

kovdan01 commented Jul 1, 2024

Fixed in llvm/llvm-project#96879

@kovdan01 kovdan01 closed this as completed Jul 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants