//===- MCCodeView.h - Machine Code CodeView support -------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Holds state from .cv_file and .cv_loc directives for later emission.
//
//===----------------------------------------------------------------------===//

#include "llvm/MC/MCCodeView.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/Line.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCObjectStreamer.h"
#include "llvm/MC/MCValue.h"
#include "llvm/Support/EndianStream.h"

using namespace llvm;
using namespace llvm::codeview;

void CodeViewContext::finish() {
  if (StrTabFragment)
    StrTabFragment->setContents(StrTab);
}

/// This is a valid number for use with .cv_loc if we've already seen a .cv_file
/// for it.
bool CodeViewContext::isValidFileNumber(unsigned FileNumber) const {
  unsigned Idx = FileNumber - 1;
  if (Idx < Files.size())
    return Files[Idx].Assigned;
  return false;
}

bool CodeViewContext::addFile(MCStreamer &OS, unsigned FileNumber,
                              StringRef Filename,
                              ArrayRef<uint8_t> ChecksumBytes,
                              uint8_t ChecksumKind) {
  assert(FileNumber > 0);
  auto FilenameOffset = addToStringTable(Filename);
  Filename = FilenameOffset.first;
  unsigned Idx = FileNumber - 1;
  if (Idx >= Files.size())
    Files.resize(Idx + 1);

  if (Filename.empty())
    Filename = "<stdin>";

  if (Files[Idx].Assigned)
    return false;

  FilenameOffset = addToStringTable(Filename);
  Filename = FilenameOffset.first;
  unsigned Offset = FilenameOffset.second;

  auto ChecksumOffsetSymbol =
      OS.getContext().createTempSymbol("checksum_offset", false);
  Files[Idx].StringTableOffset = Offset;
  Files[Idx].ChecksumTableOffset = ChecksumOffsetSymbol;
  Files[Idx].Assigned = true;
  Files[Idx].Checksum = ChecksumBytes;
  Files[Idx].ChecksumKind = ChecksumKind;

  return true;
}

MCCVFunctionInfo *CodeViewContext::getCVFunctionInfo(unsigned FuncId) {
  if (FuncId >= Functions.size())
    return nullptr;
  if (Functions[FuncId].isUnallocatedFunctionInfo())
    return nullptr;
  return &Functions[FuncId];
}

bool CodeViewContext::recordFunctionId(unsigned FuncId) {
  if (FuncId >= Functions.size())
    Functions.resize(FuncId + 1);

  // Return false if this function info was already allocated.
  if (!Functions[FuncId].isUnallocatedFunctionInfo())
    return false;

  // Mark this as an allocated normal function, and leave the rest alone.
  Functions[FuncId].ParentFuncIdPlusOne = MCCVFunctionInfo::FunctionSentinel;
  return true;
}

bool CodeViewContext::recordInlinedCallSiteId(unsigned FuncId, unsigned IAFunc,
                                              unsigned IAFile, unsigned IALine,
                                              unsigned IACol) {
  if (FuncId >= Functions.size())
    Functions.resize(FuncId + 1);

  // Return false if this function info was already allocated.
  if (!Functions[FuncId].isUnallocatedFunctionInfo())
    return false;

  MCCVFunctionInfo::LineInfo InlinedAt;
  InlinedAt.File = IAFile;
  InlinedAt.Line = IALine;
  InlinedAt.Col = IACol;

  // Mark this as an inlined call site and record call site line info.
  MCCVFunctionInfo *Info = &Functions[FuncId];
  Info->ParentFuncIdPlusOne = IAFunc + 1;
  Info->InlinedAt = InlinedAt;

  // Walk up the call chain adding this function id to the InlinedAtMap of all
  // transitive callers until we hit a real function.
  while (Info->isInlinedCallSite()) {
    InlinedAt = Info->InlinedAt;
    Info = getCVFunctionInfo(Info->getParentFuncId());
    Info->InlinedAtMap[FuncId] = InlinedAt;
  }

  return true;
}

void CodeViewContext::recordCVLoc(MCContext &Ctx, const MCSymbol *Label,
                                  unsigned FunctionId, unsigned FileNo,
                                  unsigned Line, unsigned Column,
                                  bool PrologueEnd, bool IsStmt) {
  addLineEntry(MCCVLoc{
      Label, FunctionId, FileNo, Line, Column, PrologueEnd, IsStmt});
}

std::pair<StringRef, unsigned> CodeViewContext::addToStringTable(StringRef S) {
  auto Insertion =
      StringTable.insert(std::make_pair(S, unsigned(StrTab.size())));
  // Return the string from the table, since it is stable.
  std::pair<StringRef, unsigned> Ret =
      std::make_pair(Insertion.first->first(), Insertion.first->second);
  if (Insertion.second) {
    // The string map key is always null terminated.
    StrTab.append(Ret.first.begin(), Ret.first.end() + 1);
  }
  return Ret;
}

unsigned CodeViewContext::getStringTableOffset(StringRef S) {
  // A string table offset of zero is always the empty string.
  if (S.empty())
    return 0;
  auto I = StringTable.find(S);
  assert(I != StringTable.end());
  return I->second;
}

void CodeViewContext::emitStringTable(MCObjectStreamer &OS) {
  MCContext &Ctx = OS.getContext();
  MCSymbol *StringBegin = Ctx.createTempSymbol("strtab_begin", false),
           *StringEnd = Ctx.createTempSymbol("strtab_end", false);

  OS.emitInt32(uint32_t(DebugSubsectionKind::StringTable));
  OS.emitAbsoluteSymbolDiff(StringEnd, StringBegin, 4);
  OS.emitLabel(StringBegin);

  // Put the string table data fragment here, if we haven't already put it
  // somewhere else. If somebody wants two string tables in their .s file, one
  // will just be empty.
  if (!StrTabFragment) {
    StrTabFragment = Ctx.allocFragment<MCDataFragment>();
    OS.insert(StrTabFragment);
  }

  OS.emitValueToAlignment(Align(4), 0);

  OS.emitLabel(StringEnd);
}

void CodeViewContext::emitFileChecksums(MCObjectStreamer &OS) {
  // Do nothing if there are no file checksums. Microsoft's linker rejects empty
  // CodeView substreams.
  if (Files.empty())
    return;

  MCContext &Ctx = OS.getContext();
  MCSymbol *FileBegin = Ctx.createTempSymbol("filechecksums_begin", false),
           *FileEnd = Ctx.createTempSymbol("filechecksums_end", false);

  OS.emitInt32(uint32_t(DebugSubsectionKind::FileChecksums));
  OS.emitAbsoluteSymbolDiff(FileEnd, FileBegin, 4);
  OS.emitLabel(FileBegin);

  unsigned CurrentOffset = 0;

  // Emit an array of FileChecksum entries. We index into this table using the
  // user-provided file number.  Each entry may be a variable number of bytes
  // determined by the checksum kind and size.
  for (auto File : Files) {
    OS.emitAssignment(File.ChecksumTableOffset,
                      MCConstantExpr::create(CurrentOffset, Ctx));
    CurrentOffset += 4; // String table offset.
    if (!File.ChecksumKind) {
      CurrentOffset +=
          4; // One byte each for checksum size and kind, then align to 4 bytes.
    } else {
      CurrentOffset += 2; // One byte each for checksum size and kind.
      CurrentOffset += File.Checksum.size();
      CurrentOffset = alignTo(CurrentOffset, 4);
    }

    OS.emitInt32(File.StringTableOffset);

    if (!File.ChecksumKind) {
      // There is no checksum.  Therefore zero the next two fields and align
      // back to 4 bytes.
      OS.emitInt32(0);
      continue;
    }
    OS.emitInt8(static_cast<uint8_t>(File.Checksum.size()));
    OS.emitInt8(File.ChecksumKind);
    OS.emitBytes(toStringRef(File.Checksum));
    OS.emitValueToAlignment(Align(4));
  }

  OS.emitLabel(FileEnd);

  ChecksumOffsetsAssigned = true;
}

// Output checksum table offset of the given file number.  It is possible that
// not all files have been registered yet, and so the offset cannot be
// calculated.  In this case a symbol representing the offset is emitted, and
// the value of this symbol will be fixed up at a later time.
void CodeViewContext::emitFileChecksumOffset(MCObjectStreamer &OS,
                                             unsigned FileNo) {
  unsigned Idx = FileNo - 1;

  if (Idx >= Files.size())
    Files.resize(Idx + 1);

  if (ChecksumOffsetsAssigned) {
    OS.emitSymbolValue(Files[Idx].ChecksumTableOffset, 4);
    return;
  }

  const MCSymbolRefExpr *SRE =
      MCSymbolRefExpr::create(Files[Idx].ChecksumTableOffset, OS.getContext());

  OS.emitValueImpl(SRE, 4);
}

void CodeViewContext::addLineEntry(const MCCVLoc &LineEntry) {
  size_t Offset = MCCVLines.size();
  auto I = MCCVLineStartStop.insert(
      {LineEntry.getFunctionId(), {Offset, Offset + 1}});
  if (!I.second)
    I.first->second.second = Offset + 1;
  MCCVLines.push_back(LineEntry);
}

std::vector<MCCVLoc>
CodeViewContext::getFunctionLineEntries(unsigned FuncId) {
  std::vector<MCCVLoc> FilteredLines;
  size_t LocBegin;
  size_t LocEnd;
  std::tie(LocBegin, LocEnd) = getLineExtentIncludingInlinees(FuncId);
  if (LocBegin >= LocEnd) {
    return FilteredLines;
  }

  MCCVFunctionInfo *SiteInfo = getCVFunctionInfo(FuncId);
  for (size_t Idx = LocBegin; Idx != LocEnd; ++Idx) {
    unsigned LocationFuncId = MCCVLines[Idx].getFunctionId();
    if (LocationFuncId == FuncId) {
      // This was a .cv_loc directly for FuncId, so record it.
      FilteredLines.push_back(MCCVLines[Idx]);
    } else {
      // Check if the current location is inlined in this function. If it is,
      // synthesize a statement .cv_loc at the original inlined call site.
      auto I = SiteInfo->InlinedAtMap.find(LocationFuncId);
      if (I != SiteInfo->InlinedAtMap.end()) {
        MCCVFunctionInfo::LineInfo &IA = I->second;
        // Only add the location if it differs from the previous location.
        // Large inlined calls will have many .cv_loc entries and we only need
        // one line table entry in the parent function.
        if (FilteredLines.empty() ||
            FilteredLines.back().getFileNum() != IA.File ||
            FilteredLines.back().getLine() != IA.Line ||
            FilteredLines.back().getColumn() != IA.Col) {
          FilteredLines.push_back(MCCVLoc(MCCVLines[Idx].getLabel(), FuncId,
                                          IA.File, IA.Line, IA.Col, false,
                                          false));
        }
      }
    }
  }
  return FilteredLines;
}

std::pair<size_t, size_t> CodeViewContext::getLineExtent(unsigned FuncId) {
  auto I = MCCVLineStartStop.find(FuncId);
  // Return an empty extent if there are no cv_locs for this function id.
  if (I == MCCVLineStartStop.end())
    return {~0ULL, 0};
  return I->second;
}

std::pair<size_t, size_t>
CodeViewContext::getLineExtentIncludingInlinees(unsigned FuncId) {
  size_t LocBegin;
  size_t LocEnd;
  std::tie(LocBegin, LocEnd) = getLineExtent(FuncId);

  // Include all child inline call sites in our extent.
  MCCVFunctionInfo *SiteInfo = getCVFunctionInfo(FuncId);
  if (SiteInfo) {
    for (auto &KV : SiteInfo->InlinedAtMap) {
      unsigned ChildId = KV.first;
      auto Extent = getLineExtent(ChildId);
      LocBegin = std::min(LocBegin, Extent.first);
      LocEnd = std::max(LocEnd, Extent.second);
    }
  }

  return {LocBegin, LocEnd};
}

ArrayRef<MCCVLoc> CodeViewContext::getLinesForExtent(size_t L, size_t R) {
  if (R <= L)
    return {};
  if (L >= MCCVLines.size())
    return {};
  return ArrayRef(&MCCVLines[L], R - L);
}

void CodeViewContext::emitLineTableForFunction(MCObjectStreamer &OS,
                                               unsigned FuncId,
                                               const MCSymbol *FuncBegin,
                                               const MCSymbol *FuncEnd) {
  MCContext &Ctx = OS.getContext();
  MCSymbol *LineBegin = Ctx.createTempSymbol("linetable_begin", false),
           *LineEnd = Ctx.createTempSymbol("linetable_end", false);

  OS.emitInt32(uint32_t(DebugSubsectionKind::Lines));
  OS.emitAbsoluteSymbolDiff(LineEnd, LineBegin, 4);
  OS.emitLabel(LineBegin);
  OS.emitCOFFSecRel32(FuncBegin, /*Offset=*/0);
  OS.emitCOFFSectionIndex(FuncBegin);

  // Actual line info.
  std::vector<MCCVLoc> Locs = getFunctionLineEntries(FuncId);
  bool HaveColumns = any_of(Locs, [](const MCCVLoc &LineEntry) {
    return LineEntry.getColumn() != 0;
  });
  OS.emitInt16(HaveColumns ? int(LF_HaveColumns) : 0);
  OS.emitAbsoluteSymbolDiff(FuncEnd, FuncBegin, 4);

  for (auto I = Locs.begin(), E = Locs.end(); I != E;) {
    // Emit a file segment for the run of locations that share a file id.
    unsigned CurFileNum = I->getFileNum();
    auto FileSegEnd =
        std::find_if(I, E, [CurFileNum](const MCCVLoc &Loc) {
          return Loc.getFileNum() != CurFileNum;
        });
    unsigned EntryCount = FileSegEnd - I;
    OS.AddComment("Segment for file '" +
                  Twine(StrTab[Files[CurFileNum - 1].StringTableOffset]) +
                  "' begins");
    OS.emitCVFileChecksumOffsetDirective(CurFileNum);
    OS.emitInt32(EntryCount);
    uint32_t SegmentSize = 12;
    SegmentSize += 8 * EntryCount;
    if (HaveColumns)
      SegmentSize += 4 * EntryCount;
    OS.emitInt32(SegmentSize);

    for (auto J = I; J != FileSegEnd; ++J) {
      OS.emitAbsoluteSymbolDiff(J->getLabel(), FuncBegin, 4);
      unsigned LineData = J->getLine();
      if (J->isStmt())
        LineData |= LineInfo::StatementFlag;
      OS.emitInt32(LineData);
    }
    if (HaveColumns) {
      for (auto J = I; J != FileSegEnd; ++J) {
        OS.emitInt16(J->getColumn());
        OS.emitInt16(0);
      }
    }
    I = FileSegEnd;
  }
  OS.emitLabel(LineEnd);
}

static bool compressAnnotation(uint32_t Data, SmallVectorImpl<char> &Buffer) {
  if (isUInt<7>(Data)) {
    Buffer.push_back(Data);
    return true;
  }

  if (isUInt<14>(Data)) {
    Buffer.push_back((Data >> 8) | 0x80);
    Buffer.push_back(Data & 0xff);
    return true;
  }

  if (isUInt<29>(Data)) {
    Buffer.push_back((Data >> 24) | 0xC0);
    Buffer.push_back((Data >> 16) & 0xff);
    Buffer.push_back((Data >> 8) & 0xff);
    Buffer.push_back(Data & 0xff);
    return true;
  }

  return false;
}

static bool compressAnnotation(BinaryAnnotationsOpCode Annotation,
                               SmallVectorImpl<char> &Buffer) {
  return compressAnnotation(static_cast<uint32_t>(Annotation), Buffer);
}

static uint32_t encodeSignedNumber(uint32_t Data) {
  if (Data >> 31)
    return ((-Data) << 1) | 1;
  return Data << 1;
}

void CodeViewContext::emitInlineLineTableForFunction(MCObjectStreamer &OS,
                                                     unsigned PrimaryFunctionId,
                                                     unsigned SourceFileId,
                                                     unsigned SourceLineNum,
                                                     const MCSymbol *FnStartSym,
                                                     const MCSymbol *FnEndSym) {
  // Create and insert a fragment into the current section that will be encoded
  // later.
  auto *F = MCCtx->allocFragment<MCCVInlineLineTableFragment>(
      PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym);
  OS.insert(F);
}

MCFragment *CodeViewContext::emitDefRange(
    MCObjectStreamer &OS,
    ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
    StringRef FixedSizePortion) {
  // Create and insert a fragment into the current section that will be encoded
  // later.
  auto *F =
      MCCtx->allocFragment<MCCVDefRangeFragment>(Ranges, FixedSizePortion);
  OS.insert(F);
  return F;
}

static unsigned computeLabelDiff(const MCAssembler &Asm, const MCSymbol *Begin,
                                 const MCSymbol *End) {
  MCContext &Ctx = Asm.getContext();
  MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
  const MCExpr *BeginRef = MCSymbolRefExpr::create(Begin, Variant, Ctx),
               *EndRef = MCSymbolRefExpr::create(End, Variant, Ctx);
  const MCExpr *AddrDelta =
      MCBinaryExpr::create(MCBinaryExpr::Sub, EndRef, BeginRef, Ctx);
  int64_t Result;
  bool Success = AddrDelta->evaluateKnownAbsolute(Result, Asm);
  assert(Success && "failed to evaluate label difference as absolute");
  (void)Success;
  assert(Result >= 0 && "negative label difference requested");
  assert(Result < UINT_MAX && "label difference greater than 2GB");
  return unsigned(Result);
}

void CodeViewContext::encodeInlineLineTable(const MCAssembler &Asm,
                                            MCCVInlineLineTableFragment &Frag) {
  size_t LocBegin;
  size_t LocEnd;
  std::tie(LocBegin, LocEnd) = getLineExtentIncludingInlinees(Frag.SiteFuncId);

  if (LocBegin >= LocEnd)
    return;
  ArrayRef<MCCVLoc> Locs = getLinesForExtent(LocBegin, LocEnd);
  if (Locs.empty())
    return;

  // Check that the locations are all in the same section.
#ifndef NDEBUG
  const MCSection *FirstSec = &Locs.front().getLabel()->getSection();
  for (const MCCVLoc &Loc : Locs) {
    if (&Loc.getLabel()->getSection() != FirstSec) {
      errs() << ".cv_loc " << Loc.getFunctionId() << ' ' << Loc.getFileNum()
             << ' ' << Loc.getLine() << ' ' << Loc.getColumn()
             << " is in the wrong section\n";
      llvm_unreachable(".cv_loc crosses sections");
    }
  }
#endif

  // Make an artificial start location using the function start and the inlinee
  // lines start location information. All deltas start relative to this
  // location.
  MCCVLoc StartLoc = Locs.front();
  StartLoc.setLabel(Frag.getFnStartSym());
  StartLoc.setFileNum(Frag.StartFileId);
  StartLoc.setLine(Frag.StartLineNum);
  bool HaveOpenRange = false;

  const MCSymbol *LastLabel = Frag.getFnStartSym();
  MCCVFunctionInfo::LineInfo LastSourceLoc, CurSourceLoc;
  LastSourceLoc.File = Frag.StartFileId;
  LastSourceLoc.Line = Frag.StartLineNum;

  MCCVFunctionInfo *SiteInfo = getCVFunctionInfo(Frag.SiteFuncId);

  SmallVectorImpl<char> &Buffer = Frag.getContents();
  Buffer.clear(); // Clear old contents if we went through relaxation.
  for (const MCCVLoc &Loc : Locs) {
    // Exit early if our line table would produce an oversized InlineSiteSym
    // record. Account for the ChangeCodeLength annotation emitted after the
    // loop ends.
    constexpr uint32_t InlineSiteSize = 12;
    constexpr uint32_t AnnotationSize = 8;
    size_t MaxBufferSize = MaxRecordLength - InlineSiteSize - AnnotationSize;
    if (Buffer.size() >= MaxBufferSize)
      break;

    if (Loc.getFunctionId() == Frag.SiteFuncId) {
      CurSourceLoc.File = Loc.getFileNum();
      CurSourceLoc.Line = Loc.getLine();
    } else {
      auto I = SiteInfo->InlinedAtMap.find(Loc.getFunctionId());
      if (I != SiteInfo->InlinedAtMap.end()) {
        // This .cv_loc is from a child inline call site. Use the source
        // location of the inlined call site instead of the .cv_loc directive
        // source location.
        CurSourceLoc = I->second;
      } else {
        // We've hit a cv_loc not attributed to this inline call site. Use this
        // label to end the PC range.
        if (HaveOpenRange) {
          unsigned Length = computeLabelDiff(Asm, LastLabel, Loc.getLabel());
          compressAnnotation(BinaryAnnotationsOpCode::ChangeCodeLength, Buffer);
          compressAnnotation(Length, Buffer);
          LastLabel = Loc.getLabel();
        }
        HaveOpenRange = false;
        continue;
      }
    }

    // Skip this .cv_loc if we have an open range and this isn't a meaningful
    // source location update. The current table format does not support column
    // info, so we can skip updates for those.
    if (HaveOpenRange && CurSourceLoc.File == LastSourceLoc.File &&
        CurSourceLoc.Line == LastSourceLoc.Line)
      continue;

    HaveOpenRange = true;

    if (CurSourceLoc.File != LastSourceLoc.File) {
      unsigned FileOffset = static_cast<const MCConstantExpr *>(
                                Files[CurSourceLoc.File - 1]
                                    .ChecksumTableOffset->getVariableValue())
                                ->getValue();
      compressAnnotation(BinaryAnnotationsOpCode::ChangeFile, Buffer);
      compressAnnotation(FileOffset, Buffer);
    }

    int LineDelta = CurSourceLoc.Line - LastSourceLoc.Line;
    unsigned EncodedLineDelta = encodeSignedNumber(LineDelta);
    unsigned CodeDelta = computeLabelDiff(Asm, LastLabel, Loc.getLabel());
    if (EncodedLineDelta < 0x8 && CodeDelta <= 0xf) {
      // The ChangeCodeOffsetAndLineOffset combination opcode is used when the
      // encoded line delta uses 3 or fewer set bits and the code offset fits
      // in one nibble.
      unsigned Operand = (EncodedLineDelta << 4) | CodeDelta;
      compressAnnotation(BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset,
                         Buffer);
      compressAnnotation(Operand, Buffer);
    } else {
      // Otherwise use the separate line and code deltas.
      if (LineDelta != 0) {
        compressAnnotation(BinaryAnnotationsOpCode::ChangeLineOffset, Buffer);
        compressAnnotation(EncodedLineDelta, Buffer);
      }
      compressAnnotation(BinaryAnnotationsOpCode::ChangeCodeOffset, Buffer);
      compressAnnotation(CodeDelta, Buffer);
    }

    LastLabel = Loc.getLabel();
    LastSourceLoc = CurSourceLoc;
  }

  assert(HaveOpenRange);

  unsigned EndSymLength =
      computeLabelDiff(Asm, LastLabel, Frag.getFnEndSym());
  unsigned LocAfterLength = ~0U;
  ArrayRef<MCCVLoc> LocAfter = getLinesForExtent(LocEnd, LocEnd + 1);
  if (!LocAfter.empty()) {
    // Only try to compute this difference if we're in the same section.
    const MCCVLoc &Loc = LocAfter[0];
    if (&Loc.getLabel()->getSection() == &LastLabel->getSection())
      LocAfterLength = computeLabelDiff(Asm, LastLabel, Loc.getLabel());
  }

  compressAnnotation(BinaryAnnotationsOpCode::ChangeCodeLength, Buffer);
  compressAnnotation(std::min(EndSymLength, LocAfterLength), Buffer);
}

void CodeViewContext::encodeDefRange(const MCAssembler &Asm,
                                     MCCVDefRangeFragment &Frag) {
  MCContext &Ctx = Asm.getContext();
  SmallVectorImpl<char> &Contents = Frag.getContents();
  Contents.clear();
  SmallVectorImpl<MCFixup> &Fixups = Frag.getFixups();
  Fixups.clear();
  raw_svector_ostream OS(Contents);

  // Compute all the sizes up front.
  SmallVector<std::pair<unsigned, unsigned>, 4> GapAndRangeSizes;
  const MCSymbol *LastLabel = nullptr;
  for (std::pair<const MCSymbol *, const MCSymbol *> Range : Frag.getRanges()) {
    unsigned GapSize =
        LastLabel ? computeLabelDiff(Asm, LastLabel, Range.first) : 0;
    unsigned RangeSize = computeLabelDiff(Asm, Range.first, Range.second);
    GapAndRangeSizes.push_back({GapSize, RangeSize});
    LastLabel = Range.second;
  }

  // Write down each range where the variable is defined.
  for (size_t I = 0, E = Frag.getRanges().size(); I != E;) {
    // If the range size of multiple consecutive ranges is under the max,
    // combine the ranges and emit some gaps.
    const MCSymbol *RangeBegin = Frag.getRanges()[I].first;
    unsigned RangeSize = GapAndRangeSizes[I].second;
    size_t J = I + 1;
    for (; J != E; ++J) {
      unsigned GapAndRangeSize = GapAndRangeSizes[J].first + GapAndRangeSizes[J].second;
      if (RangeSize + GapAndRangeSize > MaxDefRange)
        break;
      RangeSize += GapAndRangeSize;
    }
    unsigned NumGaps = J - I - 1;

    support::endian::Writer LEWriter(OS, llvm::endianness::little);

    unsigned Bias = 0;
    // We must split the range into chunks of MaxDefRange, this is a fundamental
    // limitation of the file format.
    do {
      uint16_t Chunk = std::min((uint32_t)MaxDefRange, RangeSize);

      const MCSymbolRefExpr *SRE = MCSymbolRefExpr::create(RangeBegin, Ctx);
      const MCBinaryExpr *BE =
          MCBinaryExpr::createAdd(SRE, MCConstantExpr::create(Bias, Ctx), Ctx);

      // Each record begins with a 2-byte number indicating how large the record
      // is.
      StringRef FixedSizePortion = Frag.getFixedSizePortion();
      // Our record is a fixed sized prefix and a LocalVariableAddrRange that we
      // are artificially constructing.
      size_t RecordSize = FixedSizePortion.size() +
                          sizeof(LocalVariableAddrRange) + 4 * NumGaps;
      // 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));
      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));
      LEWriter.write<uint16_t>(0); // Fixup for section index.
      // Write down the range's extent.
      LEWriter.write<uint16_t>(Chunk);

      // Move on to the next range.
      Bias += Chunk;
      RangeSize -= Chunk;
    } while (RangeSize > 0);

    // Emit the gaps afterwards.
    assert((NumGaps == 0 || Bias <= MaxDefRange) &&
           "large ranges should not have gaps");
    unsigned GapStartOffset = GapAndRangeSizes[I].second;
    for (++I; I != J; ++I) {
      unsigned GapSize, RangeSize;
      assert(I < GapAndRangeSizes.size());
      std::tie(GapSize, RangeSize) = GapAndRangeSizes[I];
      LEWriter.write<uint16_t>(GapStartOffset);
      LEWriter.write<uint16_t>(GapSize);
      GapStartOffset += GapSize + RangeSize;
    }
  }
}
