bool Decoder::dumpPackedEntry(const object::COFFObjectFile &COFF,
                              const SectionRef Section, uint64_t Offset,
                              unsigned Index, const RuntimeFunction &RF) {
  assert((RF.Flag() == RuntimeFunctionFlag::RFF_Packed ||
          RF.Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
         "unpacked entry cannot be treated as a packed entry");

  ErrorOr<SymbolRef> Function = getRelocatedSymbol(COFF, Section, Offset);
  if (!Function)
    Function = getSymbol(COFF, RF.BeginAddress, /*FunctionOnly=*/true);

  StringRef FunctionName;
  uint64_t FunctionAddress;
  if (Function) {
    Function->getName(FunctionName);
    Function->getAddress(FunctionAddress);
  } else {
    const pe32_header *PEHeader;
    if (COFF.getPE32Header(PEHeader))
      return false;
    FunctionAddress = PEHeader->ImageBase + RF.BeginAddress;
  }

  SW.printString("Function", formatSymbol(FunctionName, FunctionAddress));
  SW.printBoolean("Fragment",
                  RF.Flag() == RuntimeFunctionFlag::RFF_PackedFragment);
  SW.printNumber("FunctionLength", RF.FunctionLength());
  SW.startLine() << "ReturnType: " << RF.Ret() << '\n';
  SW.printBoolean("HomedParameters", RF.H());
  SW.startLine() << "SavedRegisters: ";
                 printRegisters(SavedRegisterMask(RF));
  OS << '\n';
  SW.printNumber("StackAdjustment", StackAdjustment(RF) << 2);

  return true;
}
bool Decoder::dumpUnpackedEntry(const COFFObjectFile &COFF,
                                const SectionRef Section, uint64_t Offset,
                                unsigned Index, const RuntimeFunction &RF) {
  assert(RF.Flag() == RuntimeFunctionFlag::RFF_Unpacked &&
         "packed entry cannot be treated as an unpacked entry");

  ErrorOr<SymbolRef> Function = getRelocatedSymbol(COFF, Section, Offset);
  if (!Function)
    Function = getSymbol(COFF, RF.BeginAddress, /*FunctionOnly=*/true);

  ErrorOr<SymbolRef> XDataRecord = getRelocatedSymbol(COFF, Section, Offset + 4);
  if (!XDataRecord)
    XDataRecord = getSymbol(COFF, RF.ExceptionInformationRVA());

  if (!RF.BeginAddress && !Function)
    return false;
  if (!RF.UnwindData && !XDataRecord)
    return false;

  StringRef FunctionName;
  uint64_t FunctionAddress;
  if (Function) {
    Function->getName(FunctionName);
    Function->getAddress(FunctionAddress);
  } else {
    const pe32_header *PEHeader;
    if (COFF.getPE32Header(PEHeader))
      return false;
    FunctionAddress = PEHeader->ImageBase + RF.BeginAddress;
  }

  SW.printString("Function", formatSymbol(FunctionName, FunctionAddress));

  if (XDataRecord) {
    StringRef Name;
    uint64_t Address;

    XDataRecord->getName(Name);
    XDataRecord->getAddress(Address);

    SW.printString("ExceptionRecord", formatSymbol(Name, Address));

    section_iterator SI = COFF.section_end();
    if (XDataRecord->getSection(SI))
      return false;

    return dumpXDataRecord(COFF, *SI, FunctionAddress, Address);
  } else {
    const pe32_header *PEHeader;
    if (COFF.getPE32Header(PEHeader))
      return false;

    uint64_t Address = PEHeader->ImageBase + RF.ExceptionInformationRVA();
    SW.printString("ExceptionRecord", formatSymbol("", Address));

    ErrorOr<SectionRef> Section =
      getSectionContaining(COFF, RF.ExceptionInformationRVA());
    if (!Section)
      return false;

    return dumpXDataRecord(COFF, *Section, FunctionAddress,
                           RF.ExceptionInformationRVA());
  }
}