diff --git a/llvm/lib/MC/WinCOFFObjectWriter.cpp b/llvm/lib/MC/WinCOFFObjectWriter.cpp --- a/llvm/lib/MC/WinCOFFObjectWriter.cpp +++ b/llvm/lib/MC/WinCOFFObjectWriter.cpp @@ -789,12 +789,16 @@ Reloc.Data.Type = TargetObjectWriter->getRelocType( Asm.getContext(), Target, Fixup, SymB, Asm.getBackend()); - // FIXME: Can anyone explain what this does other than adjust for the size - // of the offset? + // The *_REL32 relocations are relative to the end of the relocation, + // not to the start. if ((Header.Machine == COFF::IMAGE_FILE_MACHINE_AMD64 && Reloc.Data.Type == COFF::IMAGE_REL_AMD64_REL32) || (Header.Machine == COFF::IMAGE_FILE_MACHINE_I386 && - Reloc.Data.Type == COFF::IMAGE_REL_I386_REL32)) + Reloc.Data.Type == COFF::IMAGE_REL_I386_REL32) || + (Header.Machine == COFF::IMAGE_FILE_MACHINE_ARMNT && + Reloc.Data.Type == COFF::IMAGE_REL_ARM_REL32) || + (Header.Machine == COFF::IMAGE_FILE_MACHINE_ARM64 && + Reloc.Data.Type == COFF::IMAGE_REL_ARM64_REL32)) FixedValue += 4; if (Header.Machine == COFF::IMAGE_FILE_MACHINE_ARMNT) { diff --git a/llvm/test/MC/AArch64/coff-relocations.s b/llvm/test/MC/AArch64/coff-relocations.s --- a/llvm/test/MC/AArch64/coff-relocations.s +++ b/llvm/test/MC/AArch64/coff-relocations.s @@ -109,4 +109,4 @@ // DISASM: 4c: 20 1a 09 30 adr x0, #74565 // DATA: Contents of section .rdata: -// DATA-NEXT: 0000 2c000000 04000000 +// DATA-NEXT: 0000 30000000 08000000 diff --git a/llvm/test/MC/ARM/coff-relocations.s b/llvm/test/MC/ARM/coff-relocations.s --- a/llvm/test/MC/ARM/coff-relocations.s +++ b/llvm/test/MC/ARM/coff-relocations.s @@ -120,4 +120,4 @@ @ CHECK-RELOCATION: ] @ CHECK-DATA: Contents of section .rdata: -@ CHECK-DATA-NEXT: 0000 00000000 04000000 +@ CHECK-DATA-NEXT: 0000 04000000 08000000