This is an archive of the discontinued LLVM Phabricator instance.

[MC] Detect out of range jumps further than 2^32 bytes
ClosedPublic

Authored by dhoekwater on Jun 21 2023, 9:05 PM.

Details

Summary

On AArch64, object files may be greater than 2^32 bytes. If an
offset is greater than the max value of a 32-bit unsigned integer,
LLVM silently truncates the offset. Instead, make it return an
error.

Diff Detail

Event Timeline

dhoekwater created this revision.Jun 21 2023, 9:05 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 21 2023, 9:05 PM
dhoekwater requested review of this revision.Jun 21 2023, 9:05 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 21 2023, 9:05 PM
There was some discussion on https://reviews.llvm.org/D152841 about tests that have lots of `.space` in them, which will probably be relevant here.

fixup-out-of-range-64-bit.s may not be suitable as

  • The test fails even without the patch.
  • .space 1<<32 is very slow for MCELFStreamer. I am unsure whether we want to add a special case for -filetype=obj when -o /dev/null.

If we a test, we can craft a unittest in llvm/unittests/MC/, this may however involve a lot of boilerplate and make future refactoring of evaluateFixup difficult...

I think just fixing the code without a test is fine, but am happy to hear from others.

llvm/test/MC/AArch64/fixup-out-of-range-64-bit.s
9 ↗(On Diff #533464)

[[@LINE+1]] is deprecated lit syntax. Use [[#@LINE+1]].

Although not specifically part of this patch, for branch relocations, exposing these to the linker like we do in AArch32 would permit branches that can reach outside the section to be range-extended by thunks. For example in the test case above distant could be fixed up at link time.

Another not specifically part of this patch, is that for AArch64 we should probably give an error message when the section size gets bigger than 4 GiB as if we are resolving branches internally and not passing them on to the linker, that is the largest we can support without giving an obtuse error message. We have seen this cause trouble with GCC with an internal code-generator that generated a single gigantic .C file, without -ffunction-sections it produced a giant 4 GiB section.

I'm inclined to agree with MaskRay about not requiring a test. We do have some 32-bit systems such as Arm AArch32 that have a build bot, I'm not sure whether they would be able to cope with this test case and I'm not sure we can turn off tests on a host rather than target basis.

dhoekwater updated this revision to Diff 533699.EditedJun 22 2023, 10:57 AM

Sounds good, I'll remove the test. Testing this felt kind of gross, but I wasn't sure how strict the "any behavior-modifying change requires a test" philosophy is within LLVM.

  1. Exposing these to the linker like we do in AArch32 would permit branches that can reach outside the section to be range-extended by thunks.
  1. Another not specifically part of this patch, is that for AArch64 we should probably give an error message when the section size gets bigger than 4 GiB as if we are resolving branches internally and not passing them on to the linker, that is the largest we can support without giving an obtuse error message.
  1. Yeah, agreed. Emitting a relocation and letting the linker handle out-of-range branches should be intended behavior. One thing to keep in mind is that lld currently doesn't handle offsets greater than 4GiB for position-independent code.
  1. We shouldn't need to error out on a 4GiB+ section, right? If we're resolving branches internally (as is done in the BranchRelaxation pass when compiling C++ code), we should generate branches that are either in-range or emit relocations and can be fixed up by the linker. If we're just validating branch offsets, as is done when compiling AArch64 assembly, our current error handling should produce reasonable error output.
MaskRay accepted this revision.Jun 22 2023, 12:57 PM

Sounds good, I'll remove the test. Testing this felt kind of gross, but I wasn't sure how strict the "any behavior-modifying change requires a test" philosophy is within LLVM.

  1. Exposing these to the linker like we do in AArch32 would permit branches that can reach outside the section to be range-extended by thunks.
  1. Another not specifically part of this patch, is that for AArch64 we should probably give an error message when the section size gets bigger than 4 GiB as if we are resolving branches internally and not passing them on to the linker, that is the largest we can support without giving an obtuse error message.
  1. Yeah, agreed. Emitting a relocation and letting the linker handle out-of-range branches should be intended behavior. One thing to keep in mind is that lld currently doesn't handle offsets greater than 4GiB for position-independent code.

This limit should be fine. https://maskray.me/blog/2023-05-14-relocation-overflow-and-code-models#aarch64-code-models

"This larger range makes it unlikely for AArch64 to encounter relocation overflow issues before the binary becomes excessively oversized for x86-64."

  1. We shouldn't need to error out on a 4GiB+ section, right? If we're resolving branches internally (as is done in the BranchRelaxation pass when compiling C++ code), we should generate branches that are either in-range or emit relocations and can be fixed up by the linker. If we're just validating branch offsets, as is done when compiling AArch64 assembly, our current error handling should produce reasonable error output.

I think we do not need arbitrary restricting what we can emit in the assembly output. It's difficult to get right/test and likely not useful in practice.

" Instead, make it return an error." this sentence should be removed. Ideally add [MC] to the title of this patch.

This revision is now accepted and ready to land.Jun 22 2023, 12:57 PM

Add tag to commit message

dhoekwater retitled this revision from Detect out of range jumps further than 2^32 bytes to [MC] Detect out of range jumps further than 2^32 bytes.Jun 22 2023, 2:05 PM
This revision was landed with ongoing or failed builds.Jun 22 2023, 3:00 PM
This revision was automatically updated to reflect the committed changes.