diff options
| author | Reid Kleckner <rnk@google.com> | 2017-01-24 16:57:55 +0000 |
|---|---|---|
| committer | Reid Kleckner <rnk@google.com> | 2017-01-24 16:57:55 +0000 |
| commit | 11cf053bd19b7c98799b3cb97b9b7d34fe8ac491 (patch) | |
| tree | 22db1f05d6ec9c5fec5c01229432c5a97b54e193 | |
| parent | 1b80a146857b3184ff8efe2b0068442d4dc728ae (diff) | |
| download | bcm5719-llvm-11cf053bd19b7c98799b3cb97b9b7d34fe8ac491.tar.gz bcm5719-llvm-11cf053bd19b7c98799b3cb97b9b7d34fe8ac491.zip | |
[CodeView] Fix off-by-one error in def range gap emission
Also fixes a much worse bug where we emitted the wrong gap size for the
def range uncovered by the test for this issue.
Fixes PR31726.
llvm-svn: 292949
| -rw-r--r-- | llvm/lib/MC/MCCodeView.cpp | 12 | ||||
| -rw-r--r-- | llvm/test/MC/COFF/cv-def-range-gap.s | 24 |
2 files changed, 30 insertions, 6 deletions
diff --git a/llvm/lib/MC/MCCodeView.cpp b/llvm/lib/MC/MCCodeView.cpp index 3773542cf8a..99a5c11a498 100644 --- a/llvm/lib/MC/MCCodeView.cpp +++ b/llvm/lib/MC/MCCodeView.cpp @@ -509,17 +509,17 @@ void CodeViewContext::encodeDefRange(MCAsmLayout &Layout, // are artificially constructing. size_t RecordSize = FixedSizePortion.size() + sizeof(LocalVariableAddrRange) + 4 * NumGaps; - // Write out the recrod size. - support::endian::Writer<support::little>(OS).write<uint16_t>(RecordSize); + // Write out the record size. + LEWriter.write<uint16_t>(RecordSize); // Write out the fixed size prefix. OS << FixedSizePortion; // Make space for a fixup that will eventually have a section relative // relocation pointing at the offset where the variable becomes live. Fixups.push_back(MCFixup::create(Contents.size(), BE, FK_SecRel_4)); - Contents.resize(Contents.size() + 4); // Fixup for code start. + LEWriter.write<uint32_t>(0); // Fixup for code start. // Make space for a fixup that will record the section index for the code. Fixups.push_back(MCFixup::create(Contents.size(), BE, FK_SecRel_2)); - Contents.resize(Contents.size() + 2); // Fixup for section index. + LEWriter.write<uint16_t>(0); // Fixup for section index. // Write down the range's extent. LEWriter.write<uint16_t>(Chunk); @@ -529,7 +529,7 @@ void CodeViewContext::encodeDefRange(MCAsmLayout &Layout, } while (RangeSize > 0); // Emit the gaps afterwards. - assert((NumGaps == 0 || Bias < MaxDefRange) && + assert((NumGaps == 0 || Bias <= MaxDefRange) && "large ranges should not have gaps"); unsigned GapStartOffset = GapAndRangeSizes[I].second; for (++I; I != J; ++I) { @@ -537,7 +537,7 @@ void CodeViewContext::encodeDefRange(MCAsmLayout &Layout, assert(I < GapAndRangeSizes.size()); std::tie(GapSize, RangeSize) = GapAndRangeSizes[I]; LEWriter.write<uint16_t>(GapStartOffset); - LEWriter.write<uint16_t>(RangeSize); + LEWriter.write<uint16_t>(GapSize); GapStartOffset += GapSize + RangeSize; } } diff --git a/llvm/test/MC/COFF/cv-def-range-gap.s b/llvm/test/MC/COFF/cv-def-range-gap.s index 243e777d92e..9c153181996 100644 --- a/llvm/test/MC/COFF/cv-def-range-gap.s +++ b/llvm/test/MC/COFF/cv-def-range-gap.s @@ -38,6 +38,19 @@ # CHECK-NEXT: Range: 0x1 # CHECK-NEXT: } # CHECK-NEXT: } +# CHECK-NEXT: DefRangeRegister { +# CHECK-NEXT: Register: 23 +# CHECK-NEXT: MayHaveNoName: 0 +# CHECK-NEXT: LocalVariableAddrRange { +# CHECK-NEXT: OffsetStart: .text+0x2001C +# CHECK-NEXT: ISectStart: 0x0 +# CHECK-NEXT: Range: 0xF000 +# CHECK-NEXT: } +# CHECK-NEXT: LocalVariableAddrGap [ +# CHECK-NEXT: GapStartOffset: 0x1 +# CHECK-NEXT: Range: 0xEFFE +# CHECK-NEXT: ] +# CHECK-NEXT: } .text f: # @f @@ -62,6 +75,16 @@ f: # @f .Lbegin3: nop .Lend3: + + # Create a range that is exactly 0xF000 bytes long with a gap in the + # middle. +.Lbegin4: + nop +.Lend4: + .fill 0xeffe, 1, 0x90 +.Lbegin5: + nop +.Lend5: ret .Lfunc_end0: @@ -94,6 +117,7 @@ f: # @f .asciz "p" .Ltmp19: .cv_def_range .Lbegin0 .Lend0 .Lbegin1 .Lend1 .Lbegin2 .Lend2 .Lbegin3 .Lend3, "A\021\027\000\000\000" + .cv_def_range .Lbegin4 .Lend4 .Lbegin5 .Lend5, "A\021\027\000\000\000" .short 2 # Record length .short 4431 # Record kind: S_PROC_ID_END .Ltmp15: |

