[llvm] [ARMAsmBackend] Add checks for relocation addends in assembler (PR #109969)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 25 05:30:21 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mc
Author: None (jcohen-apple)
<details>
<summary>Changes</summary>
This PR adds checks that any addends attached to branch instructions are valid, and can be properly encoded in the branch instruction. Before this fix, the assembler would silently truncate or round invalid addend values, creating incorrect branch instructions.
---
Full diff: https://github.com/llvm/llvm-project/pull/109969.diff
3 Files Affected:
- (modified) llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp (+13-2)
- (added) llvm/test/MC/ARM/macho-relocs-with-addend-invalid.s (+28)
- (modified) llvm/test/MC/ARM/macho-relocs-with-addend.s (+2-2)
``````````diff
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
index 9f6bc31f8aa030..55f55a49e2eaa9 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
@@ -579,13 +579,24 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm,
case ARM::fixup_arm_uncondbl:
case ARM::fixup_arm_condbl:
case ARM::fixup_arm_blx:
+ // Check that the fixup value is legal.
+ Value = Value - 8;
+ if (!isInt<25>(Value)) {
+ Ctx.reportError(Fixup.getLoc(), "Relocation out of range");
+ return 0;
+ }
+ if (Value % 4 != 0) {
+ Ctx.reportError(Fixup.getLoc(), "Relocation not aligned");
+ return 0;
+ }
+
// These values don't encode the low two bits since they're always zero.
// Offset by 8 just as above.
if (const MCSymbolRefExpr *SRE =
dyn_cast<MCSymbolRefExpr>(Fixup.getValue()))
if (SRE->getKind() == MCSymbolRefExpr::VK_TLSCALL)
return 0;
- return 0xffffff & ((Value - 8) >> 2);
+ return 0xffffff & (Value >> 2);
case ARM::fixup_t2_uncondbranch: {
if (STI->getTargetTriple().isOSBinFormatCOFF() && !IsResolved &&
Value != 4) {
@@ -1121,7 +1132,7 @@ void ARMAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
assert(Offset + NumBytes <= Data.size() && "Invalid fixup offset!");
// Used to point to big endian bytes.
- unsigned FullSizeBytes;
+ unsigned FullSizeBytes = 0;
if (Endian == llvm::endianness::big) {
FullSizeBytes = getFixupKindContainerSizeBytes(Kind);
assert((Offset + FullSizeBytes) <= Data.size() && "Invalid fixup size!");
diff --git a/llvm/test/MC/ARM/macho-relocs-with-addend-invalid.s b/llvm/test/MC/ARM/macho-relocs-with-addend-invalid.s
new file mode 100644
index 00000000000000..11082ab0aebdbd
--- /dev/null
+++ b/llvm/test/MC/ARM/macho-relocs-with-addend-invalid.s
@@ -0,0 +1,28 @@
+// RUN: not llvm-mc -triple armv7-apple-darwin -filetype=obj %s 2>&1 | FileCheck %s
+
+_foo:
+ // Check that the relocation size is valid.
+
+ // CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Relocation out of range
+ bl _foo+0xfffffff00
+ // CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Relocation out of range
+ blx _foo+0xfffffff00
+ // CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Relocation out of range
+ b _foo+0xfffffff00
+ // CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Relocation out of range
+ ble _foo+0xfffffff00
+ // CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Relocation out of range
+ beq _foo+0xfffffff00
+
+ // Check that the relocation alignment is valid.
+
+ // CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Relocation not aligned
+ bl _foo+0x101
+ // CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Relocation not aligned
+ blx _foo+0x101
+ // CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Relocation not aligned
+ b _foo+0x101
+ // CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Relocation not aligned
+ ble _foo+0x101
+ // CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Relocation not aligned
+ beq _foo+0x101
diff --git a/llvm/test/MC/ARM/macho-relocs-with-addend.s b/llvm/test/MC/ARM/macho-relocs-with-addend.s
index fee930eee1b3b5..f5421baf610863 100644
--- a/llvm/test/MC/ARM/macho-relocs-with-addend.s
+++ b/llvm/test/MC/ARM/macho-relocs-with-addend.s
@@ -15,9 +15,9 @@ _with_thumb:
.globl _with_arm
.arm
_with_arm:
- bl _dest+10
+ bl _dest+12
blx _dest+20
- bne _dest+30
+ bne _dest+32
b _dest+40
.data
``````````
</details>
https://github.com/llvm/llvm-project/pull/109969
More information about the llvm-commits
mailing list