コード例 #1
0
void TargetLoweringObjectFileCOFF::
emitModuleFlags(MCStreamer &Streamer,
                ArrayRef<Module::ModuleFlagEntry> ModuleFlags,
                Mangler &Mang, const TargetMachine &TM) const {
  MDNode *LinkerOptions = nullptr;

  // Look for the "Linker Options" flag, since it's the only one we support.
  for (ArrayRef<Module::ModuleFlagEntry>::iterator
       i = ModuleFlags.begin(), e = ModuleFlags.end(); i != e; ++i) {
    const Module::ModuleFlagEntry &MFE = *i;
    StringRef Key = MFE.Key->getString();
    Metadata *Val = MFE.Val;
    if (Key == "Linker Options") {
      LinkerOptions = cast<MDNode>(Val);
      break;
    }
  }
  if (!LinkerOptions)
    return;

  // Emit the linker options to the linker .drectve section.  According to the
  // spec, this section is a space-separated string containing flags for linker.
  const MCSection *Sec = getDrectveSection();
  Streamer.SwitchSection(Sec);
  for (unsigned i = 0, e = LinkerOptions->getNumOperands(); i != e; ++i) {
    MDNode *MDOptions = cast<MDNode>(LinkerOptions->getOperand(i));
    for (unsigned ii = 0, ie = MDOptions->getNumOperands(); ii != ie; ++ii) {
      MDString *MDOption = cast<MDString>(MDOptions->getOperand(ii));
      // Lead with a space for consistency with our dllexport implementation.
      std::string Directive(" ");
      Directive.append(MDOption->getString());
      Streamer.EmitBytes(Directive);
    }
  }
}
コード例 #2
0
ファイル: llvm-dwp.cpp プロジェクト: AnachroNia/llvm
static void addAllTypesFromDWP(
    MCStreamer &Out, MapVector<uint64_t, UnitIndexEntry> &TypeIndexEntries,
    const DWARFUnitIndex &TUIndex, MCSection *OutputTypes, StringRef Types,
    const UnitIndexEntry &TUEntry, uint32_t &TypesOffset) {
  Out.SwitchSection(OutputTypes);
  for (const DWARFUnitIndex::Entry &E : TUIndex.getRows()) {
    auto *I = E.getOffsets();
    if (!I)
      continue;
    auto P = TypeIndexEntries.insert(std::make_pair(E.getSignature(), TUEntry));
    if (!P.second)
      continue;
    auto &Entry = P.first->second;
    // Zero out the debug_info contribution
    Entry.Contributions[0] = {};
    for (auto Kind : TUIndex.getColumnKinds()) {
      auto &C = Entry.Contributions[Kind - DW_SECT_INFO];
      C.Offset += I->Offset;
      C.Length = I->Length;
      ++I;
    }
    auto &C = Entry.Contributions[DW_SECT_TYPES - DW_SECT_INFO];
    Out.EmitBytes(Types.substr(
        C.Offset - TUEntry.Contributions[DW_SECT_TYPES - DW_SECT_INFO].Offset,
        C.Length));
    C.Offset = TypesOffset;
    TypesOffset += C.Length;
  }
}
コード例 #3
0
ファイル: llvm-dwp.cpp プロジェクト: AnachroNia/llvm
static void addAllTypes(MCStreamer &Out,
                        MapVector<uint64_t, UnitIndexEntry> &TypeIndexEntries,
                        MCSection *OutputTypes,
                        const std::vector<StringRef> &TypesSections,
                        const UnitIndexEntry &CUEntry, uint32_t &TypesOffset) {
  for (StringRef Types : TypesSections) {
    Out.SwitchSection(OutputTypes);
    uint32_t Offset = 0;
    DataExtractor Data(Types, true, 0);
    while (Data.isValidOffset(Offset)) {
      UnitIndexEntry Entry = CUEntry;
      // Zero out the debug_info contribution
      Entry.Contributions[0] = {};
      auto &C = Entry.Contributions[DW_SECT_TYPES - DW_SECT_INFO];
      C.Offset = TypesOffset;
      auto PrevOffset = Offset;
      // Length of the unit, including the 4 byte length field.
      C.Length = Data.getU32(&Offset) + 4;

      Data.getU16(&Offset); // Version
      Data.getU32(&Offset); // Abbrev offset
      Data.getU8(&Offset);  // Address size
      auto Signature = Data.getU64(&Offset);
      Offset = PrevOffset + C.Length;

      auto P = TypeIndexEntries.insert(std::make_pair(Signature, Entry));
      if (!P.second)
        continue;

      Out.EmitBytes(Types.substr(PrevOffset, C.Length));
      TypesOffset += C.Length;
    }
  }
}
コード例 #4
0
void TargetLoweringObjectFileCOFF::emitModuleFlags(
    MCStreamer &Streamer, ArrayRef<Module::ModuleFlagEntry> ModuleFlags,
    const TargetMachine &TM) const {
  MDNode *LinkerOptions = nullptr;

  for (const auto &MFE : ModuleFlags) {
    StringRef Key = MFE.Key->getString();
    if (Key == "Linker Options")
      LinkerOptions = cast<MDNode>(MFE.Val);
  }

  if (LinkerOptions) {
    // Emit the linker options to the linker .drectve section.  According to the
    // spec, this section is a space-separated string containing flags for
    // linker.
    MCSection *Sec = getDrectveSection();
    Streamer.SwitchSection(Sec);
    for (const auto &Option : LinkerOptions->operands()) {
      for (const auto &Piece : cast<MDNode>(Option)->operands()) {
        // Lead with a space for consistency with our dllexport implementation.
        std::string Directive(" ");
        Directive.append(cast<MDString>(Piece)->getString());
        Streamer.EmitBytes(Directive);
      }
    }
  }
}
コード例 #5
0
ファイル: CodeViewDebug.cpp プロジェクト: littleblank/llvm
static void emitNullTerminatedSymbolName(MCStreamer &OS, StringRef S) {
  // Microsoft's linker seems to have trouble with symbol names longer than
  // 0xffd8 bytes.
  S = S.substr(0, 0xffd8);
  SmallString<32> NullTerminatedString(S);
  NullTerminatedString.push_back('\0');
  OS.EmitBytes(NullTerminatedString);
}
コード例 #6
0
/// \brief Emit the optimal amount of multi-byte nops on X86.
static void EmitNops(MCStreamer &OS, unsigned NumBytes, bool Is64Bit, const MCSubtargetInfo &STI) {
  // This works only for 64bit. For 32bit we have to do additional checking if
  // the CPU supports multi-byte nops.
  assert(Is64Bit && "EmitNops only supports X86-64");
  while (NumBytes) {
    unsigned Opc, BaseReg, ScaleVal, IndexReg, Displacement, SegmentReg;
    Opc = IndexReg = Displacement = SegmentReg = 0;
    BaseReg = X86::RAX; ScaleVal = 1;
    switch (NumBytes) {
    case  0: llvm_unreachable("Zero nops?"); break;
    case  1: NumBytes -=  1; Opc = X86::NOOP; break;
    case  2: NumBytes -=  2; Opc = X86::XCHG16ar; break;
    case  3: NumBytes -=  3; Opc = X86::NOOPL; break;
    case  4: NumBytes -=  4; Opc = X86::NOOPL; Displacement = 8; break;
    case  5: NumBytes -=  5; Opc = X86::NOOPL; Displacement = 8;
             IndexReg = X86::RAX; break;
    case  6: NumBytes -=  6; Opc = X86::NOOPW; Displacement = 8;
             IndexReg = X86::RAX; break;
    case  7: NumBytes -=  7; Opc = X86::NOOPL; Displacement = 512; break;
    case  8: NumBytes -=  8; Opc = X86::NOOPL; Displacement = 512;
             IndexReg = X86::RAX; break;
    case  9: NumBytes -=  9; Opc = X86::NOOPW; Displacement = 512;
             IndexReg = X86::RAX; break;
    default: NumBytes -= 10; Opc = X86::NOOPW; Displacement = 512;
             IndexReg = X86::RAX; SegmentReg = X86::CS; break;
    }

    unsigned NumPrefixes = std::min(NumBytes, 5U);
    NumBytes -= NumPrefixes;
    for (unsigned i = 0; i != NumPrefixes; ++i)
      OS.EmitBytes("\x66");

    switch (Opc) {
    default: llvm_unreachable("Unexpected opcode"); break;
    case X86::NOOP:
      OS.EmitInstruction(MCInstBuilder(Opc), STI);
      break;
    case X86::XCHG16ar:
      OS.EmitInstruction(MCInstBuilder(Opc).addReg(X86::AX), STI);
      break;
    case X86::NOOPL:
    case X86::NOOPW:
      OS.EmitInstruction(MCInstBuilder(Opc).addReg(BaseReg).addImm(ScaleVal)
                                           .addReg(IndexReg)
                                           .addImm(Displacement)
                                           .addReg(SegmentReg), STI);
      break;
    }
  } // while (NumBytes)
}
コード例 #7
0
void TargetLoweringObjectFileCOFF::
emitModuleFlags(MCStreamer &Streamer,
                ArrayRef<Module::ModuleFlagEntry> ModuleFlags,
                Mangler &Mang, const TargetMachine &TM) const {
  MDNode *LinkerOptions = nullptr;

  // Look for the "Linker Options" flag, since it's the only one we support.
  for (ArrayRef<Module::ModuleFlagEntry>::iterator
       i = ModuleFlags.begin(), e = ModuleFlags.end(); i != e; ++i) {
    const Module::ModuleFlagEntry &MFE = *i;
    StringRef Key = MFE.Key->getString();
    Value *Val = MFE.Val;
    if (Key == "Linker Options") {
      LinkerOptions = cast<MDNode>(Val);
      break;
    }
  }
  if (!LinkerOptions)
    return;

  // Emit the linker options to the linker .drectve section.  According to the
  // spec, this section is a space-separated string containing flags for linker.
  const MCSection *Sec = getDrectveSection();
  Streamer.SwitchSection(Sec);
  for (unsigned i = 0, e = LinkerOptions->getNumOperands(); i != e; ++i) {
    MDNode *MDOptions = cast<MDNode>(LinkerOptions->getOperand(i));
    for (unsigned ii = 0, ie = MDOptions->getNumOperands(); ii != ie; ++ii) {
      MDString *MDOption = cast<MDString>(MDOptions->getOperand(ii));
      StringRef Op = MDOption->getString();
      // Lead with a space for consistency with our dllexport implementation.
      std::string Escaped(" ");
      if (Op.find(" ") != StringRef::npos) {
        // The PE-COFF spec says args with spaces must be quoted.  It doesn't say
        // how to escape quotes, but it probably uses this algorithm:
        // http://msdn.microsoft.com/en-us/library/17w5ykft(v=vs.85).aspx
        // FIXME: Reuse escaping code from Support/Windows/Program.inc
        Escaped.push_back('\"');
        Escaped.append(Op);
        Escaped.push_back('\"');
      } else {
        Escaped.append(Op);
      }
      Streamer.EmitBytes(Escaped);
    }
  }
}
コード例 #8
0
ファイル: llvm-dwp.cpp プロジェクト: AnachroNia/llvm
static std::error_code
writeStringsAndOffsets(MCStreamer &Out, StringMap<uint32_t> &Strings,
                       uint32_t &StringOffset, MCSection *StrSection,
                       MCSection *StrOffsetSection, StringRef CurStrSection,
                       StringRef CurStrOffsetSection) {
  // Could possibly produce an error or warning if one of these was non-null but
  // the other was null.
  if (CurStrSection.empty() || CurStrOffsetSection.empty())
    return std::error_code();

  DenseMap<uint32_t, uint32_t> OffsetRemapping;

  DataExtractor Data(CurStrSection, true, 0);
  uint32_t LocalOffset = 0;
  uint32_t PrevOffset = 0;
  while (const char *s = Data.getCStr(&LocalOffset)) {
    StringRef Str(s, LocalOffset - PrevOffset - 1);
    auto Pair = Strings.insert(std::make_pair(Str, StringOffset));
    if (Pair.second) {
      Out.SwitchSection(StrSection);
      Out.EmitBytes(
          StringRef(Pair.first->getKeyData(), Pair.first->getKeyLength() + 1));
      StringOffset += Str.size() + 1;
    }
    OffsetRemapping[PrevOffset] = Pair.first->second;
    PrevOffset = LocalOffset;
  }

  Data = DataExtractor(CurStrOffsetSection, true, 0);

  Out.SwitchSection(StrOffsetSection);

  uint32_t Offset = 0;
  uint64_t Size = CurStrOffsetSection.size();
  while (Offset < Size) {
    auto OldOffset = Data.getU32(&Offset);
    auto NewOffset = OffsetRemapping[OldOffset];
    Out.EmitIntValue(NewOffset, 4);
  }

  return std::error_code();
}
コード例 #9
0
ファイル: llvm-dwp.cpp プロジェクト: hoyMS/llvm
static void addAllTypes(MCStreamer &Out,
                        std::vector<UnitIndexEntry> &TypeIndexEntries,
                        MCSection *OutputTypes, StringRef Types,
                        const UnitIndexEntry &CUEntry, uint32_t &TypesOffset) {
  if (Types.empty())
    return;

  Out.SwitchSection(OutputTypes);
  uint32_t Offset = 0;
  DataExtractor Data(Types, true, 0);
  while (Data.isValidOffset(Offset)) {
    UnitIndexEntry Entry = CUEntry;
    // Zero out the debug_info contribution
    Entry.Contributions[0] = {};
    auto &C = Entry.Contributions[DW_SECT_TYPES - DW_SECT_INFO];
    C.Offset = TypesOffset;
    auto PrevOffset = Offset;
    // Length of the unit, including the 4 byte length field.
    C.Length = Data.getU32(&Offset) + 4;

    Data.getU16(&Offset); // Version
    Data.getU32(&Offset); // Abbrev offset
    Data.getU8(&Offset);  // Address size
    Entry.Signature = Data.getU64(&Offset);
    Offset = PrevOffset + C.Length;

    if (any_of(TypeIndexEntries, [&](const UnitIndexEntry &E) {
          return E.Signature == Entry.Signature;
        }))
      continue;

    Out.EmitBytes(Types.substr(PrevOffset, C.Length));
    TypesOffset += C.Length;

    TypeIndexEntries.push_back(Entry);
  }
}
コード例 #10
0
void TargetLoweringObjectFileCOFF::emitModuleMetadata(
    MCStreamer &Streamer, Module &M, const TargetMachine &TM) const {
  if (NamedMDNode *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) {
    // Emit the linker options to the linker .drectve section.  According to the
    // spec, this section is a space-separated string containing flags for
    // linker.
    MCSection *Sec = getDrectveSection();
    Streamer.SwitchSection(Sec);
    for (const auto &Option : LinkerOptions->operands()) {
      for (const auto &Piece : cast<MDNode>(Option)->operands()) {
        // Lead with a space for consistency with our dllexport implementation.
        std::string Directive(" ");
        Directive.append(cast<MDString>(Piece)->getString());
        Streamer.EmitBytes(Directive);
      }
    }
  }

  unsigned Version = 0;
  unsigned Flags = 0;
  StringRef Section;

  GetObjCImageInfo(M, Version, Flags, Section);
  if (Section.empty())
    return;

  auto &C = getContext();
  auto *S = C.getCOFFSection(
      Section, COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ,
      SectionKind::getReadOnly());
  Streamer.SwitchSection(S);
  Streamer.EmitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO")));
  Streamer.EmitIntValue(Version, 4);
  Streamer.EmitIntValue(Flags, 4);
  Streamer.AddBlankLine();
}
コード例 #11
0
ファイル: llvm-dwp.cpp プロジェクト: AnachroNia/llvm
static std::error_code write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
  const auto &MCOFI = *Out.getContext().getObjectFileInfo();
  MCSection *const StrSection = MCOFI.getDwarfStrDWOSection();
  MCSection *const StrOffsetSection = MCOFI.getDwarfStrOffDWOSection();
  MCSection *const TypesSection = MCOFI.getDwarfTypesDWOSection();
  MCSection *const CUIndexSection = MCOFI.getDwarfCUIndexSection();
  MCSection *const TUIndexSection = MCOFI.getDwarfTUIndexSection();
  const StringMap<std::pair<MCSection *, DWARFSectionKind>> KnownSections = {
      {"debug_info.dwo", {MCOFI.getDwarfInfoDWOSection(), DW_SECT_INFO}},
      {"debug_types.dwo", {MCOFI.getDwarfTypesDWOSection(), DW_SECT_TYPES}},
      {"debug_str_offsets.dwo", {StrOffsetSection, DW_SECT_STR_OFFSETS}},
      {"debug_str.dwo", {StrSection, static_cast<DWARFSectionKind>(0)}},
      {"debug_loc.dwo", {MCOFI.getDwarfLocDWOSection(), DW_SECT_LOC}},
      {"debug_line.dwo", {MCOFI.getDwarfLineDWOSection(), DW_SECT_LINE}},
      {"debug_abbrev.dwo", {MCOFI.getDwarfAbbrevDWOSection(), DW_SECT_ABBREV}},
      {"debug_cu_index", {CUIndexSection, static_cast<DWARFSectionKind>(0)}},
      {"debug_tu_index", {TUIndexSection, static_cast<DWARFSectionKind>(0)}}};

  MapVector<uint64_t, UnitIndexEntry> IndexEntries;
  MapVector<uint64_t, UnitIndexEntry> TypeIndexEntries;

  StringMap<uint32_t> Strings;
  uint32_t StringOffset = 0;

  uint32_t ContributionOffsets[8] = {};

  for (const auto &Input : Inputs) {
    auto ErrOrObj = object::ObjectFile::createObjectFile(Input);
    if (!ErrOrObj)
      return errorToErrorCode(ErrOrObj.takeError());

    UnitIndexEntry CurEntry = {};

    StringRef CurStrSection;
    StringRef CurStrOffsetSection;
    std::vector<StringRef> CurTypesSection;
    StringRef InfoSection;
    StringRef AbbrevSection;
    StringRef CurCUIndexSection;
    StringRef CurTUIndexSection;

    SmallVector<SmallString<32>, 4> UncompressedSections;

    for (const auto &Section : ErrOrObj->getBinary()->sections()) {
      if (Section.isBSS())
        continue;
      if (Section.isVirtual())
        continue;

      StringRef Name;
      if (std::error_code Err = Section.getName(Name))
        return Err;

      Name = Name.substr(Name.find_first_not_of("._"));

      StringRef Contents;
      if (auto Err = Section.getContents(Contents))
        return Err;

      if (Name.startswith("zdebug_")) {
        uint64_t OriginalSize;
        if (!zlib::isAvailable() ||
            !consumeCompressedDebugSectionHeader(Contents, OriginalSize))
          return make_error_code(std::errc::invalid_argument);
        UncompressedSections.resize(UncompressedSections.size() + 1);
        if (zlib::uncompress(Contents, UncompressedSections.back(), OriginalSize) !=
            zlib::StatusOK) {
          UncompressedSections.pop_back();
          continue;
        }
        Name = Name.substr(1);
        Contents = UncompressedSections.back();
      }

      auto SectionPair = KnownSections.find(Name);
      if (SectionPair == KnownSections.end())
        continue;

      if (DWARFSectionKind Kind = SectionPair->second.second) {
        auto Index = Kind - DW_SECT_INFO;
        if (Kind != DW_SECT_TYPES) {
          CurEntry.Contributions[Index].Offset = ContributionOffsets[Index];
          ContributionOffsets[Index] +=
              (CurEntry.Contributions[Index].Length = Contents.size());
        }

        switch (Kind) {
        case DW_SECT_INFO:
          InfoSection = Contents;
          break;
        case DW_SECT_ABBREV:
          AbbrevSection = Contents;
          break;
        default:
          break;
        }
      }

      MCSection *OutSection = SectionPair->second.first;
      if (OutSection == StrOffsetSection)
        CurStrOffsetSection = Contents;
      else if (OutSection == StrSection)
        CurStrSection = Contents;
      else if (OutSection == TypesSection)
        CurTypesSection.push_back(Contents);
      else if (OutSection == CUIndexSection)
        CurCUIndexSection = Contents;
      else if (OutSection == TUIndexSection)
        CurTUIndexSection = Contents;
      else {
        Out.SwitchSection(OutSection);
        Out.EmitBytes(Contents);
      }
    }

    if (InfoSection.empty())
      continue;

    if (!CurCUIndexSection.empty()) {
      DWARFUnitIndex CUIndex(DW_SECT_INFO);
      DataExtractor CUIndexData(CurCUIndexSection,
                                ErrOrObj->getBinary()->isLittleEndian(), 0);
      if (!CUIndex.parse(CUIndexData))
        return make_error_code(std::errc::invalid_argument);

      for (const DWARFUnitIndex::Entry &E : CUIndex.getRows()) {
        auto *I = E.getOffsets();
        if (!I)
          continue;
        auto P =
            IndexEntries.insert(std::make_pair(E.getSignature(), CurEntry));
        CompileUnitIdentifiers ID = getCUIdentifiers(
            getSubsection(AbbrevSection, E, DW_SECT_ABBREV),
            getSubsection(InfoSection, E, DW_SECT_INFO),
            getSubsection(CurStrOffsetSection, E, DW_SECT_STR_OFFSETS),
            CurStrSection);
        if (!P.second) {
          printDuplicateError(*P.first, ID, Input);
          return make_error_code(std::errc::invalid_argument);
        }
        auto &NewEntry = P.first->second;
        NewEntry.Name = ID.Name;
        NewEntry.DWOName = ID.DWOName;
        NewEntry.DWPName = Input;
        for (auto Kind : CUIndex.getColumnKinds()) {
          auto &C = NewEntry.Contributions[Kind - DW_SECT_INFO];
          C.Offset += I->Offset;
          C.Length = I->Length;
          ++I;
        }
      }

      if (!CurTypesSection.empty()) {
        assert(CurTypesSection.size() == 1);
        if (CurTUIndexSection.empty())
          return make_error_code(std::errc::invalid_argument);
        DWARFUnitIndex TUIndex(DW_SECT_TYPES);
        DataExtractor TUIndexData(CurTUIndexSection,
                                  ErrOrObj->getBinary()->isLittleEndian(), 0);
        if (!TUIndex.parse(TUIndexData))
          return make_error_code(std::errc::invalid_argument);
        addAllTypesFromDWP(Out, TypeIndexEntries, TUIndex, TypesSection,
                           CurTypesSection.front(), CurEntry,
                           ContributionOffsets[DW_SECT_TYPES - DW_SECT_INFO]);
      }
    } else {
      CompileUnitIdentifiers ID = getCUIdentifiers(
          AbbrevSection, InfoSection, CurStrOffsetSection, CurStrSection);
      auto P = IndexEntries.insert(std::make_pair(ID.Signature, CurEntry));
      if (!P.second) {
        printDuplicateError(*P.first, ID, "");
        return make_error_code(std::errc::invalid_argument);
      }
      P.first->second.Name = ID.Name;
      P.first->second.DWOName = ID.DWOName;
      addAllTypes(Out, TypeIndexEntries, TypesSection, CurTypesSection,
                  CurEntry, ContributionOffsets[DW_SECT_TYPES - DW_SECT_INFO]);
    }

    if (auto Err = writeStringsAndOffsets(Out, Strings, StringOffset,
                                          StrSection, StrOffsetSection,
                                          CurStrSection, CurStrOffsetSection))
      return Err;
  }

  // Lie about there being no info contributions so the TU index only includes
  // the type unit contribution
  ContributionOffsets[0] = 0;
  writeIndex(Out, MCOFI.getDwarfTUIndexSection(), ContributionOffsets,
             TypeIndexEntries);

  // Lie about the type contribution
  ContributionOffsets[DW_SECT_TYPES - DW_SECT_INFO] = 0;
  // Unlie about the info contribution
  ContributionOffsets[0] = 1;

  writeIndex(Out, MCOFI.getDwarfCUIndexSection(), ContributionOffsets,
             IndexEntries);

  return std::error_code();
}
コード例 #12
0
ファイル: llvm-dwp.cpp プロジェクト: mars-rover/llvm
static std::error_code write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
  const auto &MCOFI = *Out.getContext().getObjectFileInfo();
  MCSection *const StrSection = MCOFI.getDwarfStrDWOSection();
  MCSection *const StrOffsetSection = MCOFI.getDwarfStrOffDWOSection();
  const StringMap<std::pair<MCSection *, DWARFSectionKind>> KnownSections = {
      {"debug_info.dwo", {MCOFI.getDwarfInfoDWOSection(), DW_SECT_INFO}},
      {"debug_types.dwo", {MCOFI.getDwarfTypesDWOSection(), DW_SECT_TYPES}},
      {"debug_str_offsets.dwo", {StrOffsetSection, DW_SECT_STR_OFFSETS}},
      {"debug_str.dwo", {StrSection, static_cast<DWARFSectionKind>(0)}},
      {"debug_loc.dwo", {MCOFI.getDwarfLocDWOSection(), DW_SECT_LOC}},
      {"debug_abbrev.dwo", {MCOFI.getDwarfAbbrevDWOSection(), DW_SECT_ABBREV}}};

  struct UnitIndexEntry {
    uint64_t Signature;
    DWARFUnitIndex::Entry::SectionContribution Contributions[8];
  };

  std::vector<UnitIndexEntry> IndexEntries;

  StringMap<uint32_t> Strings;
  uint32_t StringOffset = 0;

  uint64_t UnitIndex = 0;
  uint32_t ContributionOffsets[8] = {};

  for (const auto &Input : Inputs) {
    auto ErrOrObj = object::ObjectFile::createObjectFile(Input);
    if (!ErrOrObj)
      return ErrOrObj.getError();

    IndexEntries.emplace_back();
    UnitIndexEntry &CurEntry = IndexEntries.back();
    CurEntry.Signature = UnitIndex++;

    StringRef CurStrSection;
    StringRef CurStrOffsetSection;

    for (const auto &Section : ErrOrObj->getBinary()->sections()) {
      StringRef Name;
      if (std::error_code Err = Section.getName(Name))
        return Err;

      auto SectionPair =
          KnownSections.find(Name.substr(Name.find_first_not_of("._")));
      if (SectionPair == KnownSections.end())
        continue;

      StringRef Contents;
      if (auto Err = Section.getContents(Contents))
        return Err;

      if (DWARFSectionKind Kind = SectionPair->second.second) {
        auto Index = Kind - DW_SECT_INFO;
        CurEntry.Contributions[Index].Offset = ContributionOffsets[Index];
        ContributionOffsets[Index] +=
            (CurEntry.Contributions[Index].Length = Contents.size());
      }

      MCSection *OutSection = SectionPair->second.first;
      if (OutSection == StrOffsetSection)
        CurStrOffsetSection = Contents;
      else if (OutSection == StrSection)
        CurStrSection = Contents;
      else {
        Out.SwitchSection(OutSection);
        Out.EmitBytes(Contents);
      }
    }

    if (auto Err = writeStringsAndOffsets(Out, Strings, StringOffset,
                                          StrSection, StrOffsetSection,
                                          CurStrSection, CurStrOffsetSection))
      return Err;
  }

  Out.SwitchSection(MCOFI.getDwarfCUIndexSection());
  Out.EmitIntValue(2, 4);                   // Version
  Out.EmitIntValue(8, 4);                   // Columns
  Out.EmitIntValue(IndexEntries.size(), 4); // Num Units
  // FIXME: This is not the right number of buckets for a real hash.
  Out.EmitIntValue(IndexEntries.size(), 4); // Num Buckets

  // Write the signatures.
  for (const auto &E : IndexEntries)
    Out.EmitIntValue(E.Signature, 8);

  // Write the indexes.
  for (size_t i = 0; i != IndexEntries.size(); ++i)
    Out.EmitIntValue(i + 1, 4);

  // Write the column headers (which sections will appear in the table)
  for (size_t i = 1; i != 9; ++i)
    Out.EmitIntValue(i, 4);

  // Write the offsets.
  for (const auto &E : IndexEntries)
    for (const auto &C : E.Contributions)
      Out.EmitIntValue(C.Offset, 4);

  // Write the lengths.
  for (const auto &E : IndexEntries)
    for (const auto &C : E.Contributions)
      Out.EmitIntValue(C.Length, 4);

  return std::error_code();
}
コード例 #13
0
ファイル: CodeViewDebug.cpp プロジェクト: elfprince13/llvm
template <typename T> static void emitRecord(MCStreamer &OS, const T &Rec) {
  OS.EmitBytes(StringRef(reinterpret_cast<const char *>(&Rec), sizeof(Rec)));
}
コード例 #14
0
void EmitCFIInstruction(MCStreamer &Streamer,
                        const MCCFIInstruction &Instr,
                        int &CFAOffset, int DataAlignmentFactor) {
  // Same as MCDwarf::EmitCFIInstruction ()
  // FIXME: Unify
  int dataAlignmentFactor = DataAlignmentFactor;
  bool VerboseAsm = Streamer.isVerboseAsm();

  switch (Instr.getOperation()) {
  case MCCFIInstruction::OpWindowSave: {
    Streamer.EmitIntValue(dwarf::DW_CFA_GNU_window_save, 1);
    return;
  }
  case MCCFIInstruction::OpUndefined: {
    unsigned Reg = Instr.getRegister();
    if (VerboseAsm) {
      Streamer.AddComment("DW_CFA_undefined");
      Streamer.AddComment(Twine("Reg ") + Twine(Reg));
    }
    Streamer.EmitIntValue(dwarf::DW_CFA_undefined, 1);
    Streamer.EmitULEB128IntValue(Reg);
    return;
  }
  case MCCFIInstruction::OpAdjustCfaOffset:
  case MCCFIInstruction::OpDefCfaOffset: {
    const bool IsRelative =
      Instr.getOperation() == MCCFIInstruction::OpAdjustCfaOffset;

    if (VerboseAsm)
      Streamer.AddComment("DW_CFA_def_cfa_offset");
    Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_offset, 1);

    if (IsRelative)
      CFAOffset += Instr.getOffset();
    else
      // The backends pass in a negative value,
      // then createDefCfaOffset () negates it
      CFAOffset = Instr.getOffset();

    if (VerboseAsm)
      Streamer.AddComment(Twine("Offset " + Twine(CFAOffset)));
    Streamer.EmitULEB128IntValue(CFAOffset);

    return;
  }
  case MCCFIInstruction::OpDefCfa: {
    if (VerboseAsm)
      Streamer.AddComment("DW_CFA_def_cfa");
    Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa, 1);

    if (VerboseAsm)
      Streamer.AddComment(Twine("Reg ") + Twine(Instr.getRegister()));
    Streamer.EmitULEB128IntValue(Instr.getRegister());

    // Backends pass a negative value to createDefCfa () which
	// negates it back
    CFAOffset = Instr.getOffset();

    if (VerboseAsm)
      Streamer.AddComment(Twine("Offset " + Twine(CFAOffset)));
    Streamer.EmitULEB128IntValue(CFAOffset);

    return;
  }

  case MCCFIInstruction::OpDefCfaRegister: {
    if (VerboseAsm)
      Streamer.AddComment("DW_CFA_def_cfa_register");
    Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_register, 1);

    if (VerboseAsm)
      Streamer.AddComment(Twine("Reg ") + Twine(Instr.getRegister()));
    Streamer.EmitULEB128IntValue(Instr.getRegister());

    return;
  }

  case MCCFIInstruction::OpOffset:
  case MCCFIInstruction::OpRelOffset: {
    const bool IsRelative =
      Instr.getOperation() == MCCFIInstruction::OpRelOffset;

    unsigned Reg = Instr.getRegister();
    int Offset = Instr.getOffset();
    if (IsRelative)
      Offset -= CFAOffset;
    Offset = Offset / dataAlignmentFactor;

    if (Offset < 0) {
      if (VerboseAsm) Streamer.AddComment("DW_CFA_offset_extended_sf");
      Streamer.EmitIntValue(dwarf::DW_CFA_offset_extended_sf, 1);
      if (VerboseAsm) Streamer.AddComment(Twine("Reg ") + Twine(Reg));
      Streamer.EmitULEB128IntValue(Reg);
      if (VerboseAsm) Streamer.AddComment(Twine("Offset ") + Twine(Offset));
      Streamer.EmitSLEB128IntValue(Offset);
    } else if (Reg < 64) {
      if (VerboseAsm) Streamer.AddComment(Twine("DW_CFA_offset + Reg(") +
                                          Twine(Reg) + ")");
      Streamer.EmitIntValue(dwarf::DW_CFA_offset + Reg, 1);
      if (VerboseAsm) Streamer.AddComment(Twine("Offset ") + Twine(Offset));
      Streamer.EmitULEB128IntValue(Offset);
    } else {
      if (VerboseAsm) Streamer.AddComment("DW_CFA_offset_extended");
      Streamer.EmitIntValue(dwarf::DW_CFA_offset_extended, 1);
      if (VerboseAsm) Streamer.AddComment(Twine("Reg ") + Twine(Reg));
      Streamer.EmitULEB128IntValue(Reg);
      if (VerboseAsm) Streamer.AddComment(Twine("Offset ") + Twine(Offset));
      Streamer.EmitULEB128IntValue(Offset);
    }
    return;
  }
  case MCCFIInstruction::OpRememberState:
    if (VerboseAsm) Streamer.AddComment("DW_CFA_remember_state");
    Streamer.EmitIntValue(dwarf::DW_CFA_remember_state, 1);
    return;
  case MCCFIInstruction::OpRestoreState:
    if (VerboseAsm) Streamer.AddComment("DW_CFA_restore_state");
    Streamer.EmitIntValue(dwarf::DW_CFA_restore_state, 1);
    return;
  case MCCFIInstruction::OpSameValue: {
    unsigned Reg = Instr.getRegister();
    if (VerboseAsm) Streamer.AddComment("DW_CFA_same_value");
    Streamer.EmitIntValue(dwarf::DW_CFA_same_value, 1);
    if (VerboseAsm) Streamer.AddComment(Twine("Reg ") + Twine(Reg));
    Streamer.EmitULEB128IntValue(Reg);
    return;
  }
  case MCCFIInstruction::OpRestore: {
    unsigned Reg = Instr.getRegister();
    if (VerboseAsm) {
      Streamer.AddComment("DW_CFA_restore");
      Streamer.AddComment(Twine("Reg ") + Twine(Reg));
    }
    Streamer.EmitIntValue(dwarf::DW_CFA_restore | Reg, 1);
    return;
  }
  case MCCFIInstruction::OpEscape:
    if (VerboseAsm) Streamer.AddComment("Escape bytes");
    Streamer.EmitBytes(Instr.getValues());
    return;
  case MCCFIInstruction::OpRegister:
	  llvm_unreachable("Unhandled case in switch");	
	  return;
  }
  llvm_unreachable("Unhandled case in switch");
}
コード例 #15
0
ファイル: llvm-dwp.cpp プロジェクト: hoyMS/llvm
static std::error_code write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
  const auto &MCOFI = *Out.getContext().getObjectFileInfo();
  MCSection *const StrSection = MCOFI.getDwarfStrDWOSection();
  MCSection *const StrOffsetSection = MCOFI.getDwarfStrOffDWOSection();
  MCSection *const TypesSection = MCOFI.getDwarfTypesDWOSection();
  MCSection *const CUIndexSection = MCOFI.getDwarfCUIndexSection();
  const StringMap<std::pair<MCSection *, DWARFSectionKind>> KnownSections = {
      {"debug_info.dwo", {MCOFI.getDwarfInfoDWOSection(), DW_SECT_INFO}},
      {"debug_types.dwo", {MCOFI.getDwarfTypesDWOSection(), DW_SECT_TYPES}},
      {"debug_str_offsets.dwo", {StrOffsetSection, DW_SECT_STR_OFFSETS}},
      {"debug_str.dwo", {StrSection, static_cast<DWARFSectionKind>(0)}},
      {"debug_loc.dwo", {MCOFI.getDwarfLocDWOSection(), DW_SECT_LOC}},
      {"debug_line.dwo", {MCOFI.getDwarfLineDWOSection(), DW_SECT_LINE}},
      {"debug_abbrev.dwo", {MCOFI.getDwarfAbbrevDWOSection(), DW_SECT_ABBREV}},
      {"debug_cu_index",
       {MCOFI.getDwarfCUIndexSection(), static_cast<DWARFSectionKind>(0)}}};

  std::vector<UnitIndexEntry> IndexEntries;
  std::vector<UnitIndexEntry> TypeIndexEntries;

  StringMap<uint32_t> Strings;
  uint32_t StringOffset = 0;

  uint32_t ContributionOffsets[8] = {};

  for (const auto &Input : Inputs) {
    auto ErrOrObj = object::ObjectFile::createObjectFile(Input);
    if (!ErrOrObj)
      return ErrOrObj.getError();

    UnitIndexEntry CurEntry = {};

    StringRef CurStrSection;
    StringRef CurStrOffsetSection;
    StringRef CurTypesSection;
    StringRef InfoSection;
    StringRef AbbrevSection;
    StringRef CurCUIndexSection;

    for (const auto &Section : ErrOrObj->getBinary()->sections()) {
      StringRef Name;
      if (std::error_code Err = Section.getName(Name))
        return Err;

      auto SectionPair =
          KnownSections.find(Name.substr(Name.find_first_not_of("._")));
      if (SectionPair == KnownSections.end())
        continue;

      StringRef Contents;
      if (auto Err = Section.getContents(Contents))
        return Err;

      if (DWARFSectionKind Kind = SectionPair->second.second) {
        auto Index = Kind - DW_SECT_INFO;
        if (Kind != DW_SECT_TYPES) {
          CurEntry.Contributions[Index].Offset = ContributionOffsets[Index];
          ContributionOffsets[Index] +=
              (CurEntry.Contributions[Index].Length = Contents.size());
        }

        switch (Kind) {
        case DW_SECT_INFO:
          InfoSection = Contents;
          break;
        case DW_SECT_ABBREV:
          AbbrevSection = Contents;
          break;
        default:
          break;
        }
      }

      MCSection *OutSection = SectionPair->second.first;
      if (OutSection == StrOffsetSection)
        CurStrOffsetSection = Contents;
      else if (OutSection == StrSection)
        CurStrSection = Contents;
      else if (OutSection == TypesSection)
        CurTypesSection = Contents;
      else if (OutSection == CUIndexSection)
        CurCUIndexSection = Contents;
      else {
        Out.SwitchSection(OutSection);
        Out.EmitBytes(Contents);
      }
    }

    assert(!AbbrevSection.empty());
    assert(!InfoSection.empty());
    if (!CurCUIndexSection.empty()) {
      DWARFUnitIndex CUIndex(DW_SECT_INFO);
      DataExtractor CUIndexData(CurCUIndexSection,
                                ErrOrObj->getBinary()->isLittleEndian(), 0);
      if (!CUIndex.parse(CUIndexData))
        return make_error_code(std::errc::invalid_argument);

      for (const DWARFUnitIndex::Entry &E : CUIndex.getRows()) {
        auto NewEntry = CurEntry;
        auto *I = E.getOffsets();
        if (!I)
          continue;
        NewEntry.Signature = E.getSignature();
        for (auto Kind : CUIndex.getColumnKinds()) {
          auto &C = NewEntry.Contributions[Kind - DW_SECT_INFO];
          C.Offset += I->Offset;
          C.Length = I->Length;
          ++I;
        }
        IndexEntries.push_back(NewEntry);
      }
    } else {
      CurEntry.Signature = getCUSignature(AbbrevSection, InfoSection);
      addAllTypes(Out, TypeIndexEntries, TypesSection, CurTypesSection,
                  CurEntry, ContributionOffsets[DW_SECT_TYPES - DW_SECT_INFO]);

      IndexEntries.push_back(CurEntry);
    }

    if (auto Err = writeStringsAndOffsets(Out, Strings, StringOffset,
                                          StrSection, StrOffsetSection,
                                          CurStrSection, CurStrOffsetSection))
      return Err;
  }

  if (!TypeIndexEntries.empty()) {
    // Lie about there being no info contributions so the TU index only includes
    // the type unit contribution
    ContributionOffsets[0] = 0;
    writeIndex(Out, MCOFI.getDwarfTUIndexSection(), ContributionOffsets,
               TypeIndexEntries);
  }

  // Lie about the type contribution
  ContributionOffsets[DW_SECT_TYPES - DW_SECT_INFO] = 0;
  // Unlie about the info contribution
  ContributionOffsets[0] = 1;

  writeIndex(Out, MCOFI.getDwarfCUIndexSection(), ContributionOffsets,
             IndexEntries);

  return std::error_code();
}