Repository navigation
cranelift-jit: assert that relocations stay within their definition - #14788
ilyas-mallah wants to merge 6 commits into
Conversation
|
Panic makes sense to me (perhaps a debug assertion? this can't happen without a bug in cranelift-codegen, so I'm not sure how much benefit there is to unconditionally checking it). And I think the check could be done inside the loop that processes the relocations right before applying them instead of iterating a second time. |
… and S390xTlsGdCall widths
…in the bounds test
Made it a panic, checked in the relocation loop right before each write. I kept it in release builds because the offsets don't only come from cranelift-codegen. DataDescription::write_data_addr and define_function_bytes take them from the caller in safe code, so a debug assertion would still let a release build write past a definition. It's one compare per relocation. |
…equence The linker rewrites the lea and call together when it relaxes the sequence, so patched_len covers 12 bytes from the displacement. The jit bounds test gains a case for it.
CompiledBlob::perform_relocations writes each relocation through a raw pointer at its offset into the definition. The only check is a debug_assert that the offset is below the size. Release builds have no check, and the debug one ignores the bytes the write covers. The offsets come from safe APIs (DataDescription::write_data_addr and write_function_addr, and the relocs of define_function_bytes), so safe code can make finalize_definitions write past a definition. In a release build, an Abs8 relocation at offset 4 of an 8-byte data object overwrote the first 4 bytes of the next object.
perform_relocations now asserts, in release builds too, that each relocation's full span lies within its definition before it writes. The span comes from a new
Reloc::patched_len, an exhaustive match so a new relocation kind has to state its width. For every kind perform_relocations handles, that width is the number of bytes it already writes there, so a relocation it applied in bounds before still passes. The new tests expect the panic from finalize_definitions and fail on main.