From 35ff3c8eef92e11e5997b485a10a32ed35c194cc Mon Sep 17 00:00:00 2001
From: Iain Sandoe <iain@sandoe.co.uk>
Date: Fri, 20 Sep 2019 08:57:23 +0100
Subject: [PATCH] [LLVM, ppc] Initial impl. of check for LO14 reloc
 validity.

LO14 discards the lower two bits of the offset, so they'd
better be 0.
---
 .../MCTargetDesc/PPCMachObjectWriter.cpp       | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMachObjectWriter.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMachObjectWriter.cpp
index 237b682db0e..3813a8048a4 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMachObjectWriter.cpp
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMachObjectWriter.cpp
@@ -315,8 +315,12 @@ void PPCMachObjectWriter::recordScatteredRelocation(
     case MachO::PPC_RELOC_SECTDIFF:
     case MachO::PPC_RELOC_LOCAL_SECTDIFF:
       break;
-    case MachO::PPC_RELOC_LO16_SECTDIFF:
     case MachO::PPC_RELOC_LO14_SECTDIFF:
+      if (FixedValue & 3)
+        Asm.getContext().reportError(Fixup.getLoc(), 
+            Twine("Offset is not valid for sect-diff operation."));
+      // FALLTHROUGH
+    case MachO::PPC_RELOC_LO16_SECTDIFF:
       OtherHalf = (FixedValue >> 16) & 0xffff;
       // applyFixupOffset longer extracts the high part because it now assumes
       // this was already done.   It looks like this is not true for the
@@ -347,8 +351,12 @@ void PPCMachObjectWriter::recordScatteredRelocation(
     uint32_t OtherHalf = 0;
     bool NeedRegularPair = true;
     switch (Type) {
-    case MachO::PPC_RELOC_LO16:
     case MachO::PPC_RELOC_LO14:
+      if (FixedValue & 3)
+        Asm.getContext().reportError(Fixup.getLoc(), 
+            Twine("Offset is not valid for operation."));
+      // FALLTHROUGH
+    case MachO::PPC_RELOC_LO16:
       OtherHalf = (FixedValue >> 16) & 0xffff;
       // see comment above.
       FixedValue &= 0xffff;
@@ -441,8 +449,12 @@ void PPCMachObjectWriter::recordRegularRelocation(
   default:
     NeedsPair = false;
    break;
-  case MachO::PPC_RELOC_LO16:
   case MachO::PPC_RELOC_LO14:
+    if (FixedValue & 3)
+        Asm.getContext().reportError(Fixup.getLoc(), 
+            Twine("Offset is not valid for LO14 reloc."));
+    // FALLTHROUGH
+  case MachO::PPC_RELOC_LO16:
       OtherHalf = (FixedValue >> 16) & 0xffff;
       FixedValue &= 0xffff;
       break;
