diff options
author | Daniel Cederman <cederman@gaisler.com> | 2018-08-27 11:43:59 +0000 |
---|---|---|
committer | Daniel Cederman <cederman@gaisler.com> | 2018-08-27 11:43:59 +0000 |
commit | db474c12e99f92977cf61461171c5cbf7a145fdd (patch) | |
tree | d9ac6f64348758df82d9bbdcdd421308c300afe2 /llvm/lib/Target/Sparc | |
parent | 6f7fef7865cf9bf0a5683e45cf672d5537919dbc (diff) | |
download | bcm5719-llvm-db474c12e99f92977cf61461171c5cbf7a145fdd.tar.gz bcm5719-llvm-db474c12e99f92977cf61461171c5cbf7a145fdd.zip |
[Sparc] Avoid writing outside array in applyFixup
Summary: 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.
Reviewers: jyknight, venkatra
Reviewed By: jyknight
Subscribers: fedor.sergeev, jrtc27, llvm-commits
Differential Revision: https://reviews.llvm.org/D50971
llvm-svn: 340736
Diffstat (limited to 'llvm/lib/Target/Sparc')
-rw-r--r-- | llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp index 5f5e2ef7d45..d7f1e3a1ab1 100644 --- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp +++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp @@ -100,6 +100,20 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) { } } +/// 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 @@ namespace { 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); } } |