[PATCH] D50971: [Sparc] Avoid writing outside array in applyFixup

Daniel Cederman via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 20 06:16:15 PDT 2018


dcederman created this revision.
dcederman added reviewers: jyknight, venkatra.
Herald added subscribers: llvm-commits, jrtc27, fedor.sergeev.

If an object file ends with a relocation that is smaller than 4 bytes we will write outside the Data array and trigger an "Invalid index" assertion.


Repository:
  rL LLVM

https://reviews.llvm.org/D50971

Files:
  lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
  test/MC/Sparc/sparc-relocations.s


Index: test/MC/Sparc/sparc-relocations.s
===================================================================
--- test/MC/Sparc/sparc-relocations.s
+++ test/MC/Sparc/sparc-relocations.s
@@ -49,3 +49,9 @@
         ! CHECK: or %g1, sym, %g3 ! encoding: [0x86,0x10,0b011AAAAA,A]
         ! CHECK-NEXT:                  !   fixup A - offset: 0, value: sym, kind: fixup_sparc_13
         or %g1, sym, %g3
+
+        ! This test needs to placed last in the file
+        ! CHECK: .half	a-.Ltmp0
+        .half a - .
+        .byte a - .
+a:
Index: lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
===================================================================
--- lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
+++ lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
@@ -100,6 +100,20 @@
   }
 }
 
+/// getFixupKindNumBytes - The number of bytes the fixup may change.
+static unsigned getFixupKindNumBytes(unsigned Kind) {
+    switch (Kind) {
+  default:
+    return 4;
+  case FK_Data_1:
+    return 1;
+  case FK_Data_2:
+    return 2;
+  case FK_Data_8:
+    return 8;
+  }
+}
+
 namespace {
   class SparcAsmBackend : public MCAsmBackend {
   protected:
@@ -290,13 +304,13 @@
       Value = adjustFixupValue(Fixup.getKind(), Value);
       if (!Value) return;           // Doesn't change encoding.
 
+      unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind());
       unsigned Offset = Fixup.getOffset();
-
       // For each byte of the fragment that the fixup touches, mask in the bits
       // from the fixup value. The Value has been "split up" into the
       // appropriate bitfields above.
-      for (unsigned i = 0; i != 4; ++i) {
-        unsigned Idx = Endian == support::little ? i : 3 - i;
+      for (unsigned i = 0; i != NumBytes; ++i) {
+        unsigned Idx = Endian == support::little ? i : (NumBytes - 1) - i;
         Data[Offset + Idx] |= uint8_t((Value >> (i * 8)) & 0xff);
       }
     }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D50971.161471.patch
Type: text/x-patch
Size: 1923 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180820/36b41042/attachment.bin>


More information about the llvm-commits mailing list