Пример #1
0
void EmitFileEntry(raw_ostream &OS, const DWARFYAML::File &File) {
  OS.write(File.Name.data(), File.Name.size());
  OS.write('\0');
  encodeULEB128(File.DirIdx, OS);
  encodeULEB128(File.ModTime, OS);
  encodeULEB128(File.Length, OS);
}
Пример #2
0
void writeCOFF(COFFParser &CP, raw_ostream &OS) {
  OS << binary_le(CP.Header.Machine)
     << binary_le(CP.Header.NumberOfSections)
     << binary_le(CP.Header.TimeDateStamp)
     << binary_le(CP.Header.PointerToSymbolTable)
     << binary_le(CP.Header.NumberOfSymbols)
     << binary_le(CP.Header.SizeOfOptionalHeader)
     << binary_le(CP.Header.Characteristics);

  // Output section table.
  for (std::vector<COFFParser::Section>::const_iterator i = CP.Sections.begin(),
                                                        e = CP.Sections.end();
                                                        i != e; ++i) {
    OS.write(i->Header.Name, COFF::NameSize);
    OS << binary_le(i->Header.VirtualSize)
       << binary_le(i->Header.VirtualAddress)
       << binary_le(i->Header.SizeOfRawData)
       << binary_le(i->Header.PointerToRawData)
       << binary_le(i->Header.PointerToRelocations)
       << binary_le(i->Header.PointerToLineNumbers)
       << binary_le(i->Header.NumberOfRelocations)
       << binary_le(i->Header.NumberOfLineNumbers)
       << binary_le(i->Header.Characteristics);
  }

  // Output section data.
  for (std::vector<COFFParser::Section>::const_iterator i = CP.Sections.begin(),
                                                        e = CP.Sections.end();
                                                        i != e; ++i) {
    if (!i->Data.empty())
      OS.write(reinterpret_cast<const char*>(&i->Data[0]), i->Data.size());
  }

  // Output symbol table.

  for (std::vector<COFFParser::Symbol>::const_iterator i = CP.Symbols.begin(),
                                                       e = CP.Symbols.end();
                                                       i != e; ++i) {
    OS.write(i->Header.Name, COFF::NameSize);
    OS << binary_le(i->Header.Value)
       << binary_le(i->Header.SectionNumber)
       << binary_le(i->Header.Type)
       << binary_le(i->Header.StorageClass)
       << binary_le(i->Header.NumberOfAuxSymbols);
    if (!i->AuxSymbols.empty())
      OS.write( reinterpret_cast<const char*>(&i->AuxSymbols[0])
              , i->AuxSymbols.size());
  }

  // Output string table.
  OS.write(&CP.StringTable[0], CP.StringTable.size());
}
Пример #3
0
void DWARFYAML::EmitPubSection(raw_ostream &OS,
                               const DWARFYAML::PubSection &Sect,
                               bool IsLittleEndian) {
  writeInteger((uint32_t)Sect.Length, OS, IsLittleEndian);
  writeInteger((uint16_t)Sect.Version, OS, IsLittleEndian);
  writeInteger((uint32_t)Sect.UnitOffset, OS, IsLittleEndian);
  writeInteger((uint32_t)Sect.UnitSize, OS, IsLittleEndian);
  for (auto Entry : Sect.Entries) {
    writeInteger((uint32_t)Entry.DieOffset, OS, IsLittleEndian);
    if (Sect.IsGNUStyle)
      writeInteger((uint32_t)Entry.Descriptor, OS, IsLittleEndian);
    OS.write(Entry.Name.data(), Entry.Name.size());
    OS.write('\0');
  }
}
Пример #4
0
/// Mangle this entity into the given stream.
void LinkEntity::mangle(raw_ostream &buffer) const {
  std::string Old = mangleOld();
  std::string New = mangleNew();

  std::string Result = NewMangling::selectMangling(Old, New);
  buffer.write(Result.data(), Result.size());
}
Пример #5
0
void wpi::write_hex(raw_ostream &S, uint64_t N, HexPrintStyle Style,
                     optional<size_t> Width) {
  const size_t kMaxWidth = 128u;

  size_t W = std::min(kMaxWidth, Width.value_or(0u));

  unsigned Nibbles = (64 - countLeadingZeros(N) + 3) / 4;
  bool Prefix = (Style == HexPrintStyle::PrefixLower ||
                 Style == HexPrintStyle::PrefixUpper);
  bool Upper =
      (Style == HexPrintStyle::Upper || Style == HexPrintStyle::PrefixUpper);
  unsigned PrefixChars = Prefix ? 2 : 0;
  unsigned NumChars =
      std::max(static_cast<unsigned>(W), std::max(1u, Nibbles) + PrefixChars);

  char NumberBuffer[kMaxWidth];
  ::memset(NumberBuffer, '0', wpi::array_lengthof(NumberBuffer));
  if (Prefix)
    NumberBuffer[1] = 'x';
  char *EndPtr = NumberBuffer + NumChars;
  char *CurPtr = EndPtr;
  while (N) {
    unsigned char x = static_cast<unsigned char>(N) % 16;
    *--CurPtr = hexdigit(x, !Upper);
    N /= 16;
  }

  S.write(NumberBuffer, NumChars);
}
Пример #6
0
int ELFState<ELFT>::writeELF(raw_ostream &OS, const ELFYAML::Object &Doc) {
  ELFState<ELFT> State(Doc);
  if (!State.buildSectionIndex())
    return 1;

  std::size_t StartSymIndex = 0;
  if (!State.buildSymbolIndex(StartSymIndex, Doc.Symbols.Local) ||
      !State.buildSymbolIndex(StartSymIndex, Doc.Symbols.Global) ||
      !State.buildSymbolIndex(StartSymIndex, Doc.Symbols.Weak))
    return 1;

  Elf_Ehdr Header;
  State.initELFHeader(Header);

  // TODO: Flesh out section header support.

  std::vector<Elf_Phdr> PHeaders;
  State.initProgramHeaders(PHeaders);

  // XXX: This offset is tightly coupled with the order that we write
  // things to `OS`.
  const size_t SectionContentBeginOffset = Header.e_ehsize +
                                           Header.e_phentsize * Header.e_phnum +
                                           Header.e_shentsize * Header.e_shnum;
  ContiguousBlobAccumulator CBA(SectionContentBeginOffset);

  std::vector<Elf_Shdr> SHeaders;
  if(!State.initSectionHeaders(SHeaders, CBA))
    return 1;

  // Populate SHeaders with implicit sections not present in the Doc
  for (const auto &Name : State.implicitSectionNames())
    if (State.SN2I.get(Name) >= SHeaders.size())
      SHeaders.push_back({});

  // Initialize the implicit sections
  auto Index = State.SN2I.get(".symtab");
  State.initSymtabSectionHeader(SHeaders[Index], SymtabType::Static, CBA);
  Index = State.SN2I.get(".strtab");
  State.initStrtabSectionHeader(SHeaders[Index], ".strtab", State.DotStrtab, CBA);
  Index = State.SN2I.get(".shstrtab");
  State.initStrtabSectionHeader(SHeaders[Index], ".shstrtab", State.DotShStrtab, CBA);
  if (State.hasDynamicSymbols()) {
    Index = State.SN2I.get(".dynsym");
    State.initSymtabSectionHeader(SHeaders[Index], SymtabType::Dynamic, CBA);
    SHeaders[Index].sh_flags |= ELF::SHF_ALLOC;
    Index = State.SN2I.get(".dynstr");
    State.initStrtabSectionHeader(SHeaders[Index], ".dynstr", State.DotDynstr, CBA);
    SHeaders[Index].sh_flags |= ELF::SHF_ALLOC;
  }

  // Now we can decide segment offsets
  State.setProgramHeaderLayout(PHeaders, SHeaders);

  OS.write((const char *)&Header, sizeof(Header));
  writeArrayData(OS, makeArrayRef(PHeaders));
  writeArrayData(OS, makeArrayRef(SHeaders));
  CBA.writeBlobToStream(OS);
  return 0;
}
Пример #7
0
static void writeWithCommas(raw_ostream &S, ArrayRef<char> Buffer) {
  assert(!Buffer.empty());

  ArrayRef<char> ThisGroup;
  int InitialDigits = ((Buffer.size() - 1) % 3) + 1;
  ThisGroup = Buffer.take_front(InitialDigits);
  S.write(ThisGroup.data(), ThisGroup.size());

  Buffer = Buffer.drop_front(InitialDigits);
  assert(Buffer.size() % 3 == 0);
  while (!Buffer.empty()) {
    S << ',';
    ThisGroup = Buffer.take_front(3);
    S.write(ThisGroup.data(), 3);
    Buffer = Buffer.drop_front(3);
  }
}
Пример #8
0
int ELFState<ELFT>::writeELF(raw_ostream &OS, const ELFYAML::Object &Doc) {
  ELFState<ELFT> State(Doc);
  if (!State.buildSectionIndex())
    return 1;

  std::size_t StartSymIndex = 0;
  if (!State.buildSymbolIndex(StartSymIndex, Doc.Symbols.Local) ||
      !State.buildSymbolIndex(StartSymIndex, Doc.Symbols.Global) ||
      !State.buildSymbolIndex(StartSymIndex, Doc.Symbols.Weak))
    return 1;

  Elf_Ehdr Header;
  State.initELFHeader(Header);

  // TODO: Flesh out section header support.
  // TODO: Program headers.

  // XXX: This offset is tightly coupled with the order that we write
  // things to `OS`.
  const size_t SectionContentBeginOffset =
      Header.e_ehsize + Header.e_shentsize * Header.e_shnum;
  ContiguousBlobAccumulator CBA(SectionContentBeginOffset);

  // Doc might not contain .symtab, .strtab and .shstrtab sections,
  // but we will emit them, so make sure to add them to ShStrTabSHeader.
  State.DotShStrtab.add(".symtab");
  State.DotShStrtab.add(".strtab");
  State.DotShStrtab.add(".shstrtab");

  std::vector<Elf_Shdr> SHeaders;
  if(!State.initSectionHeaders(SHeaders, CBA))
    return 1;

  // .symtab section.
  Elf_Shdr SymtabSHeader;
  State.initSymtabSectionHeader(SymtabSHeader, CBA);
  SHeaders.push_back(SymtabSHeader);

  // .strtab string table header.
  Elf_Shdr DotStrTabSHeader;
  State.initStrtabSectionHeader(DotStrTabSHeader, ".strtab", State.DotStrtab,
                                CBA);
  SHeaders.push_back(DotStrTabSHeader);

  // .shstrtab string table header.
  Elf_Shdr ShStrTabSHeader;
  State.initStrtabSectionHeader(ShStrTabSHeader, ".shstrtab", State.DotShStrtab,
                                CBA);
  SHeaders.push_back(ShStrTabSHeader);

  OS.write((const char *)&Header, sizeof(Header));
  writeArrayData(OS, makeArrayRef(SHeaders));
  CBA.writeBlobToStream(OS);
  return 0;
}
Пример #9
0
/// \brief Print the given string to a stream, word-wrapping it to
/// some number of columns in the process.
///
/// \param OS the stream to which the word-wrapping string will be
/// emitted.
/// \param Str the string to word-wrap and output.
/// \param Columns the number of columns to word-wrap to.
/// \param Column the column number at which the first character of \p
/// Str will be printed. This will be non-zero when part of the first
/// line has already been printed.
/// \param Bold if the current text should be bold
/// \param Indentation the number of spaces to indent any lines beyond
/// the first line.
/// \returns true if word-wrapping was required, or false if the
/// string fit on the first line.
static bool printWordWrapped(raw_ostream &OS, StringRef Str,
                             unsigned Columns,
                             unsigned Column = 0,
                             bool Bold = false,
                             unsigned Indentation = WordWrapIndentation) {
  const unsigned Length = std::min(Str.find('\n'), Str.size());
  bool TextNormal = true;

  // The string used to indent each line.
  SmallString<16> IndentStr;
  IndentStr.assign(Indentation, ' ');
  bool Wrapped = false;
  for (unsigned WordStart = 0, WordEnd; WordStart < Length;
       WordStart = WordEnd) {
    // Find the beginning of the next word.
    WordStart = skipWhitespace(WordStart, Str, Length);
    if (WordStart == Length)
      break;

    // Find the end of this word.
    WordEnd = findEndOfWord(WordStart, Str, Length, Column, Columns);

    // Does this word fit on the current line?
    unsigned WordLength = WordEnd - WordStart;
    if (Column + WordLength < Columns) {
      // This word fits on the current line; print it there.
      if (WordStart) {
        OS << ' ';
        Column += 1;
      }
      applyTemplateHighlighting(OS, Str.substr(WordStart, WordLength),
                                TextNormal, Bold);
      Column += WordLength;
      continue;
    }

    // This word does not fit on the current line, so wrap to the next
    // line.
    OS << '\n';
    OS.write(&IndentStr[0], Indentation);
    applyTemplateHighlighting(OS, Str.substr(WordStart, WordLength),
                              TextNormal, Bold);
    Column = Indentation + WordLength;
    Wrapped = true;
  }

  // Append any remaning text from the message with its existing formatting.
  applyTemplateHighlighting(OS, Str.substr(Length), TextNormal, Bold);

  assert(TextNormal && "Text highlighted at end of diagnostic message.");

  return Wrapped;
}
Пример #10
0
bool RISCVAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const {
  bool HasStdExtC = STI.getFeatureBits()[RISCV::FeatureStdExtC];
  unsigned MinNopLen = HasStdExtC ? 2 : 4;

  if ((Count % MinNopLen) != 0)
    return false;

  // The canonical nop on RISC-V is addi x0, x0, 0.
  uint64_t Nop32Count = Count / 4;
  for (uint64_t i = Nop32Count; i != 0; --i)
    OS.write("\x13\0\0\0", 4);

  // The canonical nop on RVC is c.nop.
  if (HasStdExtC) {
    uint64_t Nop16Count = (Count - Nop32Count * 4) / 2;
    for (uint64_t i = Nop16Count; i != 0; --i)
      OS.write("\x01\0", 2);
  }

  return true;
}
Пример #11
0
bool ARMAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const {
  const uint16_t Thumb1_16bitNopEncoding = 0x46c0; // using MOV r8,r8
  const uint16_t Thumb2_16bitNopEncoding = 0xbf00; // NOP
  const uint32_t ARMv4_NopEncoding = 0xe1a00000;   // using MOV r0,r0
  const uint32_t ARMv6T2_NopEncoding = 0xe320f000; // NOP
  if (isThumb()) {
    const uint16_t nopEncoding =
        hasNOP() ? Thumb2_16bitNopEncoding : Thumb1_16bitNopEncoding;
    uint64_t NumNops = Count / 2;
    for (uint64_t i = 0; i != NumNops; ++i)
      support::endian::write(OS, nopEncoding, Endian);
    if (Count & 1)
      OS << '\0';
    return true;
  }
  // ARM mode
  const uint32_t nopEncoding =
      hasNOP() ? ARMv6T2_NopEncoding : ARMv4_NopEncoding;
  uint64_t NumNops = Count / 4;
  for (uint64_t i = 0; i != NumNops; ++i)
    support::endian::write(OS, nopEncoding, Endian);
  // FIXME: should this function return false when unable to write exactly
  // 'Count' bytes with NOP encodings?
  switch (Count % 4) {
  default:
    break; // No leftover bytes to write
  case 1:
    OS << '\0';
    break;
  case 2:
    OS.write("\0\0", 2);
    break;
  case 3:
    OS.write("\0\0\xa0", 3);
    break;
  }

  return true;
}
Пример #12
0
void DWARFYAML::EmitDebugAbbrev(raw_ostream &OS, const DWARFYAML::Data &DI) {
  for (auto AbbrevDecl : DI.AbbrevDecls) {
    encodeULEB128(AbbrevDecl.Code, OS);
    encodeULEB128(AbbrevDecl.Tag, OS);
    OS.write(AbbrevDecl.Children);
    for (auto Attr : AbbrevDecl.Attributes) {
      encodeULEB128(Attr.Attribute, OS);
      encodeULEB128(Attr.Form, OS);
    }
    encodeULEB128(0, OS);
    encodeULEB128(0, OS);
  }
}
/// WriteBitcodeToFile - Write the specified module to the specified output
/// stream.
void llvm::NaClWriteBitcodeToFile(const Module *M, raw_ostream &Out,
                                  bool AcceptSupportedOnly) {
  SmallVector<char, 0> Buffer;
  Buffer.reserve(256*1024);

  // Emit the module into the buffer.
  {
    NaClBitstreamWriter Stream(Buffer);
    NaClWriteHeader(Stream, AcceptSupportedOnly);
    WriteModule(M, Stream);
  }

  // Write the generated bitstream to "Out".
  Out.write((char*)&Buffer.front(), Buffer.size());
}
Пример #14
0
static void
printBSDMemberHeader(raw_ostream &Out, uint64_t Pos, StringRef Name,
                     const sys::TimePoint<std::chrono::seconds> &ModTime,
                     unsigned UID, unsigned GID, unsigned Perms,
                     unsigned Size) {
  uint64_t PosAfterHeader = Pos + 60 + Name.size();
  // Pad so that even 64 bit object files are aligned.
  unsigned Pad = OffsetToAlignment(PosAfterHeader, 8);
  unsigned NameWithPadding = Name.size() + Pad;
  printWithSpacePadding(Out, Twine("#1/") + Twine(NameWithPadding), 16);
  printRestOfMemberHeader(Out, ModTime, UID, GID, Perms,
                          NameWithPadding + Size);
  Out << Name;
  while (Pad--)
    Out.write(uint8_t(0));
}
Пример #15
0
  void EmitData(raw_ostream &Out, key_type_ref, data_type_ref V, offset_type) {
    using namespace llvm::support;
    endian::Writer<little> LE(Out);
    for (const auto &ProfileData : *V) {
      const InstrProfRecord &ProfRecord = ProfileData.second;
      SummaryBuilder->addRecord(ProfRecord);

      LE.write<uint64_t>(ProfileData.first); // Function hash
      LE.write<uint64_t>(ProfRecord.Counts.size());
      for (uint64_t I : ProfRecord.Counts)
        LE.write<uint64_t>(I);

      // Write value data
      std::unique_ptr<ValueProfData> VDataPtr =
          ValueProfData::serializeFrom(ProfileData.second);
      uint32_t S = VDataPtr->getSize();
      VDataPtr->swapBytesFromHost(ValueProfDataEndianness);
      Out.write((const char *)VDataPtr.get(), S);
    }
  }
Пример #16
0
static void write_unsigned_impl(raw_ostream &S, T N, size_t MinDigits,
                                IntegerStyle Style, bool IsNegative) {
  static_assert(std::is_unsigned<T>::value, "Value is not unsigned!");

  char NumberBuffer[128];
  std::memset(NumberBuffer, '0', sizeof(NumberBuffer));

  size_t Len = 0;
  Len = format_to_buffer(N, NumberBuffer);

  if (IsNegative)
    S << '-';

  if (Len < MinDigits && Style != IntegerStyle::Number) {
    for (size_t I = Len; I < MinDigits; ++I)
      S << '0';
  }

  if (Style == IntegerStyle::Number) {
    writeWithCommas(S, ArrayRef<char>(std::end(NumberBuffer) - Len, Len));
  } else {
    S.write(std::end(NumberBuffer) - Len, Len);
  }
}
Пример #17
0
static int writeELF(raw_ostream &OS, const ELFYAML::Object &Doc) {
  using namespace llvm::ELF;
  typedef typename object::ELFFile<ELFT>::Elf_Ehdr Elf_Ehdr;
  typedef typename object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr;

  const ELFYAML::FileHeader &Hdr = Doc.Header;

  Elf_Ehdr Header;
  zero(Header);
  Header.e_ident[EI_MAG0] = 0x7f;
  Header.e_ident[EI_MAG1] = 'E';
  Header.e_ident[EI_MAG2] = 'L';
  Header.e_ident[EI_MAG3] = 'F';
  Header.e_ident[EI_CLASS] = ELFT::Is64Bits ? ELFCLASS64 : ELFCLASS32;
  bool IsLittleEndian = ELFT::TargetEndianness == support::little;
  Header.e_ident[EI_DATA] = IsLittleEndian ? ELFDATA2LSB : ELFDATA2MSB;
  Header.e_ident[EI_VERSION] = EV_CURRENT;
  Header.e_ident[EI_OSABI] = Hdr.OSABI;
  Header.e_ident[EI_ABIVERSION] = 0;
  Header.e_type = Hdr.Type;
  Header.e_machine = Hdr.Machine;
  Header.e_version = EV_CURRENT;
  Header.e_entry = Hdr.Entry;
  Header.e_flags = Hdr.Flags;
  Header.e_ehsize = sizeof(Elf_Ehdr);

  // TODO: Flesh out section header support.
  // TODO: Program headers.

  Header.e_shentsize = sizeof(Elf_Shdr);
  // Immediately following the ELF header.
  Header.e_shoff = sizeof(Header);
  const std::vector<ELFYAML::Section> &Sections = Doc.Sections;
  // "+ 4" for
  // - SHT_NULL entry (placed first, i.e. 0'th entry)
  // - symbol table (.symtab) (placed third to last)
  // - string table (.strtab) (placed second to last)
  // - section header string table. (placed last)
  Header.e_shnum = Sections.size() + 4;
  // Place section header string table last.
  Header.e_shstrndx = Header.e_shnum - 1;
  const unsigned DotStrtabSecNo = Header.e_shnum - 2;

  // XXX: This offset is tightly coupled with the order that we write
  // things to `OS`.
  const size_t SectionContentBeginOffset =
      Header.e_ehsize + Header.e_shentsize * Header.e_shnum;
  ContiguousBlobAccumulator CBA(SectionContentBeginOffset);
  SectionNameToIdxMap SN2I;
  for (unsigned i = 0, e = Sections.size(); i != e; ++i) {
    StringRef Name = Sections[i].Name;
    if (Name.empty())
      continue;
    // "+ 1" to take into account the SHT_NULL entry.
    if (SN2I.addName(Name, i + 1)) {
      errs() << "error: Repeated section name: '" << Name
             << "' at YAML section number " << i << ".\n";
      return 1;
    }
  }

  ELFState<ELFT> State(CBA, DotStrtabSecNo, SN2I);

  StringTableBuilder SHStrTab;
  std::vector<Elf_Shdr> SHeaders;
  {
    // Ensure SHN_UNDEF entry is present. An all-zero section header is a
    // valid SHN_UNDEF entry since SHT_NULL == 0.
    Elf_Shdr SHdr;
    zero(SHdr);
    SHeaders.push_back(SHdr);
  }
  for (const auto &Sec : Sections) {
    Elf_Shdr SHeader;
    zero(SHeader);
    SHeader.sh_name = SHStrTab.addString(Sec.Name);
    SHeader.sh_type = Sec.Type;
    SHeader.sh_flags = Sec.Flags;
    SHeader.sh_addr = Sec.Address;

    Sec.Content.writeAsBinary(CBA.getOSAndAlignedOffset(SHeader.sh_offset));
    SHeader.sh_size = Sec.Content.binary_size();

    if (!Sec.Link.empty()) {
      unsigned Index;
      if (SN2I.lookupSection(Sec.Link, Index)) {
        errs() << "error: Unknown section referenced: '" << Sec.Link
               << "' at YAML section '" << Sec.Name << "'.\n";
        return 1;
      }
      SHeader.sh_link = Index;
    }
    SHeader.sh_info = 0;
    SHeader.sh_addralign = Sec.AddressAlign;
    SHeader.sh_entsize = 0;
    SHeaders.push_back(SHeader);
  }

  // .symtab section.
  Elf_Shdr SymtabSHeader;
  zero(SymtabSHeader);
  SymtabSHeader.sh_name = SHStrTab.addString(StringRef(".symtab"));
  handleSymtabSectionHeader<ELFT>(Doc.Symbols, State, SymtabSHeader);
  SHeaders.push_back(SymtabSHeader);

  // .strtab string table header.
  Elf_Shdr DotStrTabSHeader;
  zero(DotStrTabSHeader);
  DotStrTabSHeader.sh_name = SHStrTab.addString(StringRef(".strtab"));
  createStringTableSectionHeader(DotStrTabSHeader, State.getStringTable(), CBA);
  SHeaders.push_back(DotStrTabSHeader);

  // Section header string table header.
  Elf_Shdr SHStrTabSHeader;
  zero(SHStrTabSHeader);
  SHStrTabSHeader.sh_name = SHStrTab.addString(StringRef(".shstrtab"));
  createStringTableSectionHeader(SHStrTabSHeader, SHStrTab, CBA);
  SHeaders.push_back(SHStrTabSHeader);

  OS.write((const char *)&Header, sizeof(Header));
  writeArrayData(OS, makeArrayRef(SHeaders));
  CBA.writeBlobToStream(OS);
  return 0;
}
Пример #18
0
 void HandleTranslationUnit(ASTContext &Ctx) override {
   auto &SerializedAST = Buffer->Data;
   OS->write(SerializedAST.data(), SerializedAST.size());
   OS->flush();
 }
Пример #19
0
void wasm::writeStr(raw_ostream &OS, StringRef String, const Twine &Msg) {
  debugWrite(OS.tell(),
             Msg + " [str[" + Twine(String.size()) + "]: " + String + "]");
  encodeULEB128(String.size(), OS);
  OS.write(String.data(), String.size());
}
Пример #20
0
static void writeArrayData(raw_ostream &OS, ArrayRef<T> A) {
  OS.write((const char *)A.data(), arrayDataSize(A));
}
Пример #21
0
void R600MCCodeEmitter::EmitByte(unsigned int Byte, raw_ostream &OS) const {
  OS.write((uint8_t) Byte & 0xff);
}
Пример #22
0
 void EmitKey(raw_ostream &Out, key_type_ref K, offset_type N) {
   Out.write(K.data(), N);
 }
Пример #23
0
int WasmWriter::writeWasm(raw_ostream &OS) {
  // Write headers
  OS.write(wasm::WasmMagic, sizeof(wasm::WasmMagic));
  writeUint32(OS, Obj.Header.Version);

  // Write each section
  for (const std::unique_ptr<WasmYAML::Section> &Sec : Obj.Sections) {
    encodeULEB128(Sec->Type, OS);

    std::string OutString;
    raw_string_ostream StringStream(OutString);
    if (auto S = dyn_cast<WasmYAML::CustomSection>(Sec.get())) {
      if (auto Err = writeSectionContent(StringStream, *S))
        return Err;
    } else if (auto S = dyn_cast<WasmYAML::TypeSection>(Sec.get())) {
      if (auto Err = writeSectionContent(StringStream, *S))
        return Err;
    } else if (auto S = dyn_cast<WasmYAML::ImportSection>(Sec.get())) {
      if (auto Err = writeSectionContent(StringStream, *S))
        return Err;
    } else if (auto S = dyn_cast<WasmYAML::FunctionSection>(Sec.get())) {
      if (auto Err = writeSectionContent(StringStream, *S))
        return Err;
    } else if (auto S = dyn_cast<WasmYAML::TableSection>(Sec.get())) {
      if (auto Err = writeSectionContent(StringStream, *S))
        return Err;
    } else if (auto S = dyn_cast<WasmYAML::MemorySection>(Sec.get())) {
      if (auto Err = writeSectionContent(StringStream, *S))
        return Err;
    } else if (auto S = dyn_cast<WasmYAML::GlobalSection>(Sec.get())) {
      if (auto Err = writeSectionContent(StringStream, *S))
        return Err;
    } else if (auto S = dyn_cast<WasmYAML::ExportSection>(Sec.get())) {
      if (auto Err = writeSectionContent(StringStream, *S))
        return Err;
    } else if (auto S = dyn_cast<WasmYAML::StartSection>(Sec.get())) {
      if (auto Err = writeSectionContent(StringStream, *S))
        return Err;
    } else if (auto S = dyn_cast<WasmYAML::ElemSection>(Sec.get())) {
      if (auto Err = writeSectionContent(StringStream, *S))
        return Err;
    } else if (auto S = dyn_cast<WasmYAML::CodeSection>(Sec.get())) {
      if (auto Err = writeSectionContent(StringStream, *S))
        return Err;
    } else if (auto S = dyn_cast<WasmYAML::DataSection>(Sec.get())) {
      if (auto Err = writeSectionContent(StringStream, *S))
        return Err;
    } else {
      errs() << "Unknown section type: " << Sec->Type << "\n";
      return 1;
    }
    StringStream.flush();

    // Write the section size followed by the content
    encodeULEB128(OutString.size(), OS);
    OS << OutString;
  }

  // write reloc sections for any section that have relocations
  for (const std::unique_ptr<WasmYAML::Section> &Sec : Obj.Sections) {
    if (Sec->Relocations.empty())
      continue;

    encodeULEB128(wasm::WASM_SEC_CUSTOM, OS);
    std::string OutString;
    raw_string_ostream StringStream(OutString);
    writeRelocSection(StringStream, *Sec);
    StringStream.flush();

    encodeULEB128(OutString.size(), OS);
    OS << OutString;
  }

  return 0;
}
static void EmitMSInlineAsmStr(const char *AsmStr, const MachineInstr *MI,
                               MachineModuleInfo *MMI, int InlineAsmVariant,
                               AsmPrinter *AP, unsigned LocCookie,
                               raw_ostream &OS) {
  // Switch to the inline assembly variant.
  OS << "\t.intel_syntax\n\t";

  const char *LastEmitted = AsmStr; // One past the last character emitted.
  unsigned NumOperands = MI->getNumOperands();

  while (*LastEmitted) {
    switch (*LastEmitted) {
    default: {
      // Not a special case, emit the string section literally.
      const char *LiteralEnd = LastEmitted+1;
      while (*LiteralEnd && *LiteralEnd != '{' && *LiteralEnd != '|' &&
             *LiteralEnd != '}' && *LiteralEnd != '$' && *LiteralEnd != '\n')
        ++LiteralEnd;

      OS.write(LastEmitted, LiteralEnd-LastEmitted);
      LastEmitted = LiteralEnd;
      break;
    }
    case '\n':
      ++LastEmitted;   // Consume newline character.
      OS << '\n';      // Indent code with newline.
      break;
    case '$': {
      ++LastEmitted;   // Consume '$' character.
      bool Done = true;

      // Handle escapes.
      switch (*LastEmitted) {
      default: Done = false; break;
      case '$':
        ++LastEmitted;  // Consume second '$' character.
        break;
      }
      if (Done) break;

      // If we have ${:foo}, then this is not a real operand reference, it is a
      // "magic" string reference, just like in .td files.  Arrange to call
      // PrintSpecial.
      if (LastEmitted[0] == '{' && LastEmitted[1] == ':') {
        LastEmitted += 2;
        const char *StrStart = LastEmitted;
        const char *StrEnd = strchr(StrStart, '}');
        if (!StrEnd)
          report_fatal_error("Unterminated ${:foo} operand in inline asm"
                             " string: '" + Twine(AsmStr) + "'");

        std::string Val(StrStart, StrEnd);
        AP->PrintSpecial(MI, OS, Val.c_str());
        LastEmitted = StrEnd+1;
        break;
      }

      const char *IDStart = LastEmitted;
      const char *IDEnd = IDStart;
      while (*IDEnd >= '0' && *IDEnd <= '9') ++IDEnd;

      unsigned Val;
      if (StringRef(IDStart, IDEnd-IDStart).getAsInteger(10, Val))
        report_fatal_error("Bad $ operand number in inline asm string: '" +
                           Twine(AsmStr) + "'");
      LastEmitted = IDEnd;

      if (Val >= NumOperands-1)
        report_fatal_error("Invalid $ operand number in inline asm string: '" +
                           Twine(AsmStr) + "'");

      // Okay, we finally have a value number.  Ask the target to print this
      // operand!
      unsigned OpNo = InlineAsm::MIOp_FirstOperand;

      bool Error = false;

      // Scan to find the machine operand number for the operand.
      for (; Val; --Val) {
        if (OpNo >= MI->getNumOperands()) break;
        unsigned OpFlags = MI->getOperand(OpNo).getImm();
        OpNo += InlineAsm::getNumOperandRegisters(OpFlags) + 1;
      }

      // We may have a location metadata attached to the end of the
      // instruction, and at no point should see metadata at any
      // other point while processing. It's an error if so.
      if (OpNo >= MI->getNumOperands() ||
          MI->getOperand(OpNo).isMetadata()) {
        Error = true;
      } else {
        unsigned OpFlags = MI->getOperand(OpNo).getImm();
        ++OpNo;  // Skip over the ID number.

        if (InlineAsm::isMemKind(OpFlags)) {
          Error = AP->PrintAsmMemoryOperand(MI, OpNo, InlineAsmVariant,
                                            /*Modifier*/ nullptr, OS);
        } else {
          Error = AP->PrintAsmOperand(MI, OpNo, InlineAsmVariant,
                                      /*Modifier*/ nullptr, OS);
        }
      }
      if (Error) {
        std::string msg;
        raw_string_ostream Msg(msg);
        Msg << "invalid operand in inline asm: '" << AsmStr << "'";
        MMI->getModule()->getContext().emitError(LocCookie, Msg.str());
      }
      break;
    }
    }
  }
  OS << "\n\t.att_syntax\n" << (char)0;  // null terminate string.
}
static void EmitGCCInlineAsmStr(const char *AsmStr, const MachineInstr *MI,
                                MachineModuleInfo *MMI, int InlineAsmVariant,
                                int AsmPrinterVariant, AsmPrinter *AP,
                                unsigned LocCookie, raw_ostream &OS) {
  int CurVariant = -1;            // The number of the {.|.|.} region we are in.
  const char *LastEmitted = AsmStr; // One past the last character emitted.
  unsigned NumOperands = MI->getNumOperands();

  OS << '\t';

  while (*LastEmitted) {
    switch (*LastEmitted) {
    default: {
      // Not a special case, emit the string section literally.
      const char *LiteralEnd = LastEmitted+1;
      while (*LiteralEnd && *LiteralEnd != '{' && *LiteralEnd != '|' &&
             *LiteralEnd != '}' && *LiteralEnd != '$' && *LiteralEnd != '\n')
        ++LiteralEnd;
      if (CurVariant == -1 || CurVariant == AsmPrinterVariant)
        OS.write(LastEmitted, LiteralEnd-LastEmitted);
      LastEmitted = LiteralEnd;
      break;
    }
    case '\n':
      ++LastEmitted;   // Consume newline character.
      OS << '\n';      // Indent code with newline.
      break;
    case '$': {
      ++LastEmitted;   // Consume '$' character.
      bool Done = true;

      // Handle escapes.
      switch (*LastEmitted) {
      default: Done = false; break;
      case '$':     // $$ -> $
        if (CurVariant == -1 || CurVariant == AsmPrinterVariant)
          OS << '$';
        ++LastEmitted;  // Consume second '$' character.
        break;
      case '(':             // $( -> same as GCC's { character.
        ++LastEmitted;      // Consume '(' character.
        if (CurVariant != -1)
          report_fatal_error("Nested variants found in inline asm string: '" +
                             Twine(AsmStr) + "'");
        CurVariant = 0;     // We're in the first variant now.
        break;
      case '|':
        ++LastEmitted;  // consume '|' character.
        if (CurVariant == -1)
          OS << '|';       // this is gcc's behavior for | outside a variant
        else
          ++CurVariant;   // We're in the next variant.
        break;
      case ')':         // $) -> same as GCC's } char.
        ++LastEmitted;  // consume ')' character.
        if (CurVariant == -1)
          OS << '}';     // this is gcc's behavior for } outside a variant
        else
          CurVariant = -1;
        break;
      }
      if (Done) break;

      bool HasCurlyBraces = false;
      if (*LastEmitted == '{') {     // ${variable}
        ++LastEmitted;               // Consume '{' character.
        HasCurlyBraces = true;
      }

      // If we have ${:foo}, then this is not a real operand reference, it is a
      // "magic" string reference, just like in .td files.  Arrange to call
      // PrintSpecial.
      if (HasCurlyBraces && *LastEmitted == ':') {
        ++LastEmitted;
        const char *StrStart = LastEmitted;
        const char *StrEnd = strchr(StrStart, '}');
        if (!StrEnd)
          report_fatal_error("Unterminated ${:foo} operand in inline asm"
                             " string: '" + Twine(AsmStr) + "'");

        std::string Val(StrStart, StrEnd);
        AP->PrintSpecial(MI, OS, Val.c_str());
        LastEmitted = StrEnd+1;
        break;
      }

      const char *IDStart = LastEmitted;
      const char *IDEnd = IDStart;
      while (*IDEnd >= '0' && *IDEnd <= '9') ++IDEnd;

      unsigned Val;
      if (StringRef(IDStart, IDEnd-IDStart).getAsInteger(10, Val))
        report_fatal_error("Bad $ operand number in inline asm string: '" +
                           Twine(AsmStr) + "'");
      LastEmitted = IDEnd;

      char Modifier[2] = { 0, 0 };

      if (HasCurlyBraces) {
        // If we have curly braces, check for a modifier character.  This
        // supports syntax like ${0:u}, which correspond to "%u0" in GCC asm.
        if (*LastEmitted == ':') {
          ++LastEmitted;    // Consume ':' character.
          if (*LastEmitted == 0)
            report_fatal_error("Bad ${:} expression in inline asm string: '" +
                               Twine(AsmStr) + "'");

          Modifier[0] = *LastEmitted;
          ++LastEmitted;    // Consume modifier character.
        }

        if (*LastEmitted != '}')
          report_fatal_error("Bad ${} expression in inline asm string: '" +
                             Twine(AsmStr) + "'");
        ++LastEmitted;    // Consume '}' character.
      }

      if (Val >= NumOperands-1)
        report_fatal_error("Invalid $ operand number in inline asm string: '" +
                           Twine(AsmStr) + "'");

      // Okay, we finally have a value number.  Ask the target to print this
      // operand!
      if (CurVariant == -1 || CurVariant == AsmPrinterVariant) {
        unsigned OpNo = InlineAsm::MIOp_FirstOperand;

        bool Error = false;

        // Scan to find the machine operand number for the operand.
        for (; Val; --Val) {
          if (OpNo >= MI->getNumOperands()) break;
          unsigned OpFlags = MI->getOperand(OpNo).getImm();
          OpNo += InlineAsm::getNumOperandRegisters(OpFlags) + 1;
        }

        // We may have a location metadata attached to the end of the
        // instruction, and at no point should see metadata at any
        // other point while processing. It's an error if so.
        if (OpNo >= MI->getNumOperands() ||
            MI->getOperand(OpNo).isMetadata()) {
          Error = true;
        } else {
          unsigned OpFlags = MI->getOperand(OpNo).getImm();
          ++OpNo;  // Skip over the ID number.

          if (Modifier[0] == 'l') { // Labels are target independent.
            if (MI->getOperand(OpNo).isBlockAddress()) {
              const BlockAddress *BA = MI->getOperand(OpNo).getBlockAddress();
              MCSymbol *Sym = AP->GetBlockAddressSymbol(BA);
              Sym->print(OS, AP->MAI);
            } else if (MI->getOperand(OpNo).isMBB()) {
              const MCSymbol *Sym = MI->getOperand(OpNo).getMBB()->getSymbol();
              Sym->print(OS, AP->MAI);
            } else {
              Error = true;
            }
          } else {
            if (InlineAsm::isMemKind(OpFlags)) {
              Error = AP->PrintAsmMemoryOperand(MI, OpNo, InlineAsmVariant,
                                                Modifier[0] ? Modifier : nullptr,
                                                OS);
            } else {
              Error = AP->PrintAsmOperand(MI, OpNo, InlineAsmVariant,
                                          Modifier[0] ? Modifier : nullptr, OS);
            }
          }
        }
        if (Error) {
          std::string msg;
          raw_string_ostream Msg(msg);
          Msg << "invalid operand in inline asm: '" << AsmStr << "'";
          MMI->getModule()->getContext().emitError(LocCookie, Msg.str());
        }
      }
      break;
    }
    }
  }
  OS << '\n' << (char)0;  // null terminate string.
}
Пример #26
0
static void writeSymbolTable(raw_ostream &Out, object::Archive::Kind Kind,
                             bool Deterministic, ArrayRef<MemberData> Members,
                             StringRef StringTable) {
  // We don't write a symbol table on an archive with no members -- except on
  // Darwin, where the linker will abort unless the archive has a symbol table.
  if (StringTable.empty() && !isDarwin(Kind))
    return;

  unsigned NumSyms = 0;
  for (const MemberData &M : Members)
    NumSyms += M.Symbols.size();

  unsigned Size = 0;
  unsigned OffsetSize = is64BitKind(Kind) ? sizeof(uint64_t) : sizeof(uint32_t);

  Size += OffsetSize; // Number of entries
  if (isBSDLike(Kind))
    Size += NumSyms * OffsetSize * 2; // Table
  else
    Size += NumSyms * OffsetSize; // Table
  if (isBSDLike(Kind))
    Size += OffsetSize; // byte count
  Size += StringTable.size();
  // ld64 expects the members to be 8-byte aligned for 64-bit content and at
  // least 4-byte aligned for 32-bit content.  Opt for the larger encoding
  // uniformly.
  // We do this for all bsd formats because it simplifies aligning members.
  unsigned Alignment = isBSDLike(Kind) ? 8 : 2;
  unsigned Pad = OffsetToAlignment(Size, Alignment);
  Size += Pad;

  if (isBSDLike(Kind)) {
    const char *Name = is64BitKind(Kind) ? "__.SYMDEF_64" : "__.SYMDEF";
    printBSDMemberHeader(Out, Out.tell(), Name, now(Deterministic), 0, 0, 0,
                         Size);
  } else {
    const char *Name = is64BitKind(Kind) ? "/SYM64" : "";
    printGNUSmallMemberHeader(Out, Name, now(Deterministic), 0, 0, 0, Size);
  }

  uint64_t Pos = Out.tell() + Size;

  if (isBSDLike(Kind))
    printNBits(Out, Kind, NumSyms * 2 * OffsetSize);
  else
    printNBits(Out, Kind, NumSyms);

  for (const MemberData &M : Members) {
    for (unsigned StringOffset : M.Symbols) {
      if (isBSDLike(Kind))
        printNBits(Out, Kind, StringOffset);
      printNBits(Out, Kind, Pos); // member offset
    }
    Pos += M.Header.size() + M.Data.size() + M.Padding.size();
  }

  if (isBSDLike(Kind))
    // byte count of the string table
    printNBits(Out, Kind, StringTable.size());
  Out << StringTable;

  while (Pad--)
    Out.write(uint8_t(0));
}
Пример #27
0
static int writeUint32(raw_ostream &OS, uint32_t Value) {
  char Data[sizeof(Value)];
  support::endian::write32le(Data, Value);
  OS.write(Data, sizeof(Data));
  return 0;
}
Пример #28
0
static int writeUint8(raw_ostream &OS, uint8_t Value) {
  char Data[sizeof(Value)];
  memcpy(Data, &Value, sizeof(Data));
  OS.write(Data, sizeof(Data));
  return 0;
}
Пример #29
0
/// Mangle this entity into the given stream.
void LinkEntity::mangle(raw_ostream &buffer) const {
  std::string Result = mangleAsString();
  buffer.write(Result.data(), Result.size());
}
Пример #30
0
bool writeCOFF(COFFParser &CP, raw_ostream &OS) {
  OS << binary_le(CP.Obj.Header.Machine)
     << binary_le(CP.Obj.Header.NumberOfSections)
     << binary_le(CP.Obj.Header.TimeDateStamp)
     << binary_le(CP.Obj.Header.PointerToSymbolTable)
     << binary_le(CP.Obj.Header.NumberOfSymbols)
     << binary_le(CP.Obj.Header.SizeOfOptionalHeader)
     << binary_le(CP.Obj.Header.Characteristics);

  // Output section table.
  for (std::vector<COFFYAML::Section>::iterator i = CP.Obj.Sections.begin(),
                                                e = CP.Obj.Sections.end();
                                                i != e; ++i) {
    OS.write(i->Header.Name, COFF::NameSize);
    OS << binary_le(i->Header.VirtualSize)
       << binary_le(i->Header.VirtualAddress)
       << binary_le(i->Header.SizeOfRawData)
       << binary_le(i->Header.PointerToRawData)
       << binary_le(i->Header.PointerToRelocations)
       << binary_le(i->Header.PointerToLineNumbers)
       << binary_le(i->Header.NumberOfRelocations)
       << binary_le(i->Header.NumberOfLineNumbers)
       << binary_le(i->Header.Characteristics);
  }

  unsigned CurSymbol = 0;
  StringMap<unsigned> SymbolTableIndexMap;
  for (std::vector<COFFYAML::Symbol>::iterator I = CP.Obj.Symbols.begin(),
                                               E = CP.Obj.Symbols.end();
       I != E; ++I) {
    SymbolTableIndexMap[I->Name] = CurSymbol;
    CurSymbol += 1 + I->Header.NumberOfAuxSymbols;
  }

  // Output section data.
  for (std::vector<COFFYAML::Section>::iterator i = CP.Obj.Sections.begin(),
                                                e = CP.Obj.Sections.end();
                                                i != e; ++i) {
    i->SectionData.writeAsBinary(OS);
    for (unsigned I2 = 0, E2 = i->Relocations.size(); I2 != E2; ++I2) {
      const COFFYAML::Relocation &R = i->Relocations[I2];
      uint32_t SymbolTableIndex = SymbolTableIndexMap[R.SymbolName];
      OS << binary_le(R.VirtualAddress)
         << binary_le(SymbolTableIndex)
         << binary_le(R.Type);
    }
  }

  // Output symbol table.

  for (std::vector<COFFYAML::Symbol>::const_iterator i = CP.Obj.Symbols.begin(),
                                                     e = CP.Obj.Symbols.end();
                                                     i != e; ++i) {
    OS.write(i->Header.Name, COFF::NameSize);
    OS << binary_le(i->Header.Value)
       << binary_le(i->Header.SectionNumber)
       << binary_le(i->Header.Type)
       << binary_le(i->Header.StorageClass)
       << binary_le(i->Header.NumberOfAuxSymbols);

    if (i->FunctionDefinition)
      OS << binary_le(i->FunctionDefinition->TagIndex)
         << binary_le(i->FunctionDefinition->TotalSize)
         << binary_le(i->FunctionDefinition->PointerToLinenumber)
         << binary_le(i->FunctionDefinition->PointerToNextFunction)
         << zeros(i->FunctionDefinition->unused);
    if (i->bfAndefSymbol)
      OS << zeros(i->bfAndefSymbol->unused1)
         << binary_le(i->bfAndefSymbol->Linenumber)
         << zeros(i->bfAndefSymbol->unused2)
         << binary_le(i->bfAndefSymbol->PointerToNextFunction)
         << zeros(i->bfAndefSymbol->unused3);
    if (i->WeakExternal)
      OS << binary_le(i->WeakExternal->TagIndex)
         << binary_le(i->WeakExternal->Characteristics)
         << zeros(i->WeakExternal->unused);
    if (!i->File.empty()) {
      uint32_t NumberOfAuxRecords =
          (i->File.size() + COFF::SymbolSize - 1) / COFF::SymbolSize;
      uint32_t NumberOfAuxBytes = NumberOfAuxRecords * COFF::SymbolSize;
      uint32_t NumZeros = NumberOfAuxBytes - i->File.size();
      OS.write(i->File.data(), i->File.size());
      for (uint32_t Padding = 0; Padding < NumZeros; ++Padding)
        OS.write(0);
    }
    if (i->SectionDefinition)
      OS << binary_le(i->SectionDefinition->Length)
         << binary_le(i->SectionDefinition->NumberOfRelocations)
         << binary_le(i->SectionDefinition->NumberOfLinenumbers)
         << binary_le(i->SectionDefinition->CheckSum)
         << binary_le(i->SectionDefinition->Number)
         << binary_le(i->SectionDefinition->Selection)
         << zeros(i->SectionDefinition->unused);
    if (i->CLRToken)
      OS << binary_le(i->CLRToken->AuxType)
         << zeros(i->CLRToken->unused1)
         << binary_le(i->CLRToken->SymbolTableIndex)
         << zeros(i->CLRToken->unused2);
  }

  // Output string table.
  OS.write(&CP.StringTable[0], CP.StringTable.size());
  return true;
}