Skip to content

[ARM] [Windows] Error out on branch relocations that require a symbol offset #101906

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

Merged
merged 1 commit into from
Aug 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,14 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm,
return 0;
return 0xffffff & ((Value - 8) >> 2);
case ARM::fixup_t2_uncondbranch: {
if (STI->getTargetTriple().isOSBinFormatCOFF() && !IsResolved &&
Value != 4) {
// MSVC link.exe and lld do not support this relocation type
// with a non-zero offset. ("Value" is offset by 4 at this point.)
Ctx.reportError(Fixup.getLoc(),
"cannot perform a PC-relative fixup with a non-zero "
"symbol offset");
}
Value = Value - 4;
if (!isInt<25>(Value)) {
Ctx.reportError(Fixup.getLoc(), "Relocation out of range");
Expand Down Expand Up @@ -637,6 +645,14 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm,
Ctx.reportError(Fixup.getLoc(), "Relocation out of range");
return 0;
}
if (STI->getTargetTriple().isOSBinFormatCOFF() && !IsResolved &&
Value != 4) {
// MSVC link.exe and lld do not support this relocation type
// with a non-zero offset. ("Value" is offset by 4 at this point.)
Ctx.reportError(Fixup.getLoc(),
"cannot perform a PC-relative fixup with a non-zero "
"symbol offset");
}

// The value doesn't encode the low bit (always zero) and is offset by
// four. The 32-bit immediate value is encoded as
Expand Down Expand Up @@ -666,6 +682,14 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm,
Endian == llvm::endianness::little);
}
case ARM::fixup_arm_thumb_blx: {
if (STI->getTargetTriple().isOSBinFormatCOFF() && !IsResolved &&
Value != 4) {
// MSVC link.exe and lld do not support this relocation type
// with a non-zero offset. ("Value" is offset by 4 at this point.)
Ctx.reportError(Fixup.getLoc(),
"cannot perform a PC-relative fixup with a non-zero "
"symbol offset");
}
// The value doesn't encode the low two bits (always zero) and is offset by
// four (see fixup_arm_thumb_cp). The 32-bit immediate value is encoded as
// imm32 = SignExtend(S:I1:I2:imm10H:imm10L:00)
Expand Down
38 changes: 38 additions & 0 deletions llvm/test/MC/ARM/Windows/branch-reloc-offset.s
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// RUN: llvm-mc -triple thumbv7-windows-gnu -filetype obj %s -o - | llvm-objdump -D -r - | FileCheck %s
// RUN: not llvm-mc -triple thumbv7-windows-gnu -filetype obj --defsym ERR=1 %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR

.text
main:
Expand Down Expand Up @@ -55,3 +56,40 @@ main:
// CHECK: e: bf00 nop
// CHECK: 00000010 <.Lother_target>:
// CHECK: 10: 4770 bx lr

.ifdef ERR
.section "other2", "xr"
err:
nop

// Test errors, if referencing a symbol with an offset

b .Lerr_target+4
// ERR: [[#@LINE-1]]:5: error: cannot perform a PC-relative fixup with a non-zero symbol offset
bl .Lerr_target+4
// ERR: [[#@LINE-1]]:5: error: cannot perform a PC-relative fixup with a non-zero symbol offset
blx .Lerr_target+4
// ERR: [[#@LINE-1]]:5: error: cannot perform a PC-relative fixup with a non-zero symbol offset

// Test errors, if referencing a private label which lacks .def/.scl/.type/.endef, in another
// section, without an offset. Such symbols are omitted from the output symbol table, so the
// relocation can't reference them. Such relocations usually are made towards the base of the
// section plus an offset, but such an offset is not supported with this relocation.

b .Lerr_target2
// ERR: [[#@LINE-1]]:5: error: cannot perform a PC-relative fixup with a non-zero symbol offset

.def .Lerr_target
.scl 3
.type 32
.endef
.Lerr_target:
nop
nop
bx lr

.section "other3", "xr"
nop
.Lerr_target2:
bx lr
.endif
Loading