diff --git a/llvm/lib/MCCAS/MCCASObjectV1.cpp b/llvm/lib/MCCAS/MCCASObjectV1.cpp index 49820bd2dcf33..5a3964094f28d 100644 --- a/llvm/lib/MCCAS/MCCASObjectV1.cpp +++ b/llvm/lib/MCCAS/MCCASObjectV1.cpp @@ -2433,6 +2433,15 @@ Error MCCASBuilder::buildFragments() { continue; SmallVector FinalFragmentContents; + // Set the RelocationBuffer to be an empty ArrayRef, and the + // RelocationBufferIndex to zero if the architecture is 32-bit, because we + // do not support relocation partitioning on 32-bit platforms. With this, + // partitionFragment will put all the fragment contents in the + // FinalFragmentContents, and the Addends buffer will be empty. + if (ObjectWriter.getAddressSize() == 4) { + RelocationBuffer = ArrayRef(); + RelocationBufferIndex = 0; + } partitionFragment(Layout, Addends, FinalFragmentContents, RelocationBuffer, F, RelocationBufferIndex, ObjectWriter.Target.isLittleEndian()); @@ -2834,25 +2843,32 @@ MCCASReader::reconstructSection(SmallVectorImpl &SectionBuffer, /// copied the addend out of the Addends at a particular offset, we should /// skip all relocations that matches the same offset. int64_t PrevOffset = -1; - for (auto Reloc : Relocations.back()) { - auto RelocationOffsetInSection = getRelocationOffset(Reloc); - if (PrevOffset == RelocationOffsetInSection) - continue; - auto RelocationSize = - getRelocationSize(Reloc, getEndian() == support::little); - /// NumOfBytesToReloc: This denotes the number of bytes needed to be copied - /// into the \p SectionBuffer before we copy the next addend. - auto NumOfBytesToReloc = RelocationOffsetInSection - SectionBuffer.size(); - // Copy the contents of the fragment till the next relocation. - SectionBuffer.append(FragmentBuffer.begin() + FragmentIndex, - FragmentBuffer.begin() + FragmentIndex + - NumOfBytesToReloc); - FragmentIndex += NumOfBytesToReloc; - // Copy the relocation addend. - SectionBuffer.append(Addends.begin() + AddendBufferIndex, - Addends.begin() + AddendBufferIndex + RelocationSize); - AddendBufferIndex += RelocationSize; - PrevOffset = RelocationOffsetInSection; + /// If the \p Addends buffer is empty, there was no AddendsRef for this + /// section, this is either because no \p Relocations exist in this section, + /// or this is 32-bit architecture, where we do not support relocation + /// partitioning. + if (!Addends.empty()) { + for (auto Reloc : Relocations.back()) { + auto RelocationOffsetInSection = getRelocationOffset(Reloc); + if (PrevOffset == RelocationOffsetInSection) + continue; + auto RelocationSize = + getRelocationSize(Reloc, getEndian() == support::little); + /// NumOfBytesToReloc: This denotes the number of bytes needed to be + /// copied into the \p SectionBuffer before we copy the next addend. + auto NumOfBytesToReloc = RelocationOffsetInSection - SectionBuffer.size(); + // Copy the contents of the fragment till the next relocation. + SectionBuffer.append(FragmentBuffer.begin() + FragmentIndex, + FragmentBuffer.begin() + FragmentIndex + + NumOfBytesToReloc); + FragmentIndex += NumOfBytesToReloc; + // Copy the relocation addend. + SectionBuffer.append(Addends.begin() + AddendBufferIndex, + Addends.begin() + AddendBufferIndex + + RelocationSize); + AddendBufferIndex += RelocationSize; + PrevOffset = RelocationOffsetInSection; + } } // Copy any remaining bytes of the fragment into the SectionBuffer. SectionBuffer.append(FragmentBuffer.begin() + FragmentIndex, diff --git a/llvm/test/CAS/test-reloc-mccas-32bit-arm.s b/llvm/test/CAS/test-reloc-mccas-32bit-arm.s new file mode 100644 index 0000000000000..669b84eb5815f --- /dev/null +++ b/llvm/test/CAS/test-reloc-mccas-32bit-arm.s @@ -0,0 +1,9 @@ +# This test tests to make sure mccas can handle scattered relocations properly on 32 bit arm + +# RUN: rm -rf %t && mkdir -p %t +# RUN: llvm-mc --cas=%t/cas --cas-backend --mccas-verify -triple=armv7-apple-darwin10 -filetype=obj -o %t/reloc.o %s + + movw r0, :lower16:(fn2-L1) +L1: +fn2: + diff --git a/llvm/test/CAS/test-reloc-mccas-32bit.s b/llvm/test/CAS/test-reloc-mccas-32bit.s new file mode 100644 index 0000000000000..4d91aa0b26bf6 --- /dev/null +++ b/llvm/test/CAS/test-reloc-mccas-32bit.s @@ -0,0 +1,6 @@ +# This test tests to make sure mccas can handle scattered relocations properly on 32 bit x86 + +# RUN: rm -rf %t && mkdir -p %t +# RUN: llvm-mc --cas=%t/cas --cas-backend --mccas-verify -triple=i386-apple-macosx10.4 -filetype=obj -o %t/reloc.o %s + movl y+4, %ecx +.zerofill __DATA,__common,y,8,3