/// Detect the likely line ending style of \p FromFile by examining the first /// newline found within it. static StringRef DetectEOL(const MemoryBuffer &FromFile) { // detect what line endings the file uses, so that added content does not mix // the style const char *Pos = strchr(FromFile.getBufferStart(), '\n'); if (Pos == NULL) return "\n"; if (Pos + 1 < FromFile.getBufferEnd() && Pos[1] == '\r') return "\n\r"; if (Pos - 1 >= FromFile.getBufferStart() && Pos[-1] == '\r') return "\r\n"; return "\n"; }
/// Detect the likely line ending style of \p FromFile by examining the first /// newline found within it. static StringRef DetectEOL(const MemoryBuffer &FromFile) { // Detect what line endings the file uses, so that added content does not mix // the style. We need to check for "\r\n" first because "\n\r" will match // "\r\n\r\n". const char *Pos = strchr(FromFile.getBufferStart(), '\n'); if (!Pos) return "\n"; if (Pos - 1 >= FromFile.getBufferStart() && Pos[-1] == '\r') return "\r\n"; if (Pos + 1 < FromFile.getBufferEnd() && Pos[1] == '\r') return "\n\r"; return "\n"; }
line_iterator::line_iterator(const MemoryBuffer &Buffer, bool SkipBlanks, char CommentMarker) : Buffer(Buffer.getBufferSize() ? &Buffer : nullptr), CommentMarker(CommentMarker), SkipBlanks(SkipBlanks), LineNumber(1), CurrentLine(Buffer.getBufferSize() ? Buffer.getBufferStart() : nullptr, 0) { // Ensure that if we are constructed on a non-empty memory buffer that it is // a null terminated buffer. if (Buffer.getBufferSize()) { assert(Buffer.getBufferEnd()[0] == '\0'); // Make sure we don't skip a leading newline if we're keeping blanks if (SkipBlanks || !isAtLineEnd(Buffer.getBufferStart())) advance(); } }
void WriteBundle(raw_fd_ostream &OS, MemoryBuffer &Input) final { Module *M = AuxModule.get(); // Create the new section name, it will consist of the reserved prefix // concatenated with the triple. std::string SectionName = OFFLOAD_BUNDLER_MAGIC_STR; SectionName += CurrentTriple; // Create the constant with the content of the section. For the input we are // bundling into (the host input), this is just a place-holder, so a single // byte is sufficient. assert(HostInputIndex != ~0u && "Host input index undefined??"); Constant *Content; if (NumberOfProcessedInputs == HostInputIndex + 1) { uint8_t Byte[] = {0}; Content = ConstantDataArray::get(VMContext, Byte); } else Content = ConstantDataArray::get( VMContext, ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>( Input.getBufferStart()), Input.getBufferSize())); // Create the global in the desired section. We don't want these globals in // the symbol table, so we mark them private. auto *GV = new GlobalVariable(*M, Content->getType(), /*IsConstant=*/true, GlobalVariable::PrivateLinkage, Content); GV->setSection(SectionName); }
bool CodeGenCoverage::parse(MemoryBuffer &Buffer, StringRef BackendName) { const char *CurPtr = Buffer.getBufferStart(); while (CurPtr != Buffer.getBufferEnd()) { // Read the backend name from the input. const char *LexedBackendName = CurPtr; while (*CurPtr++ != 0) ; if (CurPtr == Buffer.getBufferEnd()) return false; // Data is invalid, expected rule id's to follow. bool IsForThisBackend = BackendName.equals(LexedBackendName); while (CurPtr != Buffer.getBufferEnd()) { if (std::distance(CurPtr, Buffer.getBufferEnd()) < 8) return false; // Data is invalid. Not enough bytes for another rule id. uint64_t RuleID = support::endian::read64(CurPtr, support::native); CurPtr += 8; // ~0ull terminates the rule id list. if (RuleID == ~0ull) break; // Anything else, is recorded or ignored depending on whether it's // intended for the backend we're interested in. if (IsForThisBackend) setCovered(RuleID); } } return true; }
/// getNewMemBuffer - Allocate a new MemoryBuffer of the specified size that /// is completely initialized to zeros. Note that the caller should /// initialize the memory allocated by this method. The memory is owned by /// the MemoryBuffer object. MemoryBuffer *MemoryBuffer::getNewMemBuffer(size_t Size, const char *BufferName) { MemoryBuffer *SB = getNewUninitMemBuffer(Size, BufferName); if (!SB) return 0; memset(const_cast<char*>(SB->getBufferStart()), 0, Size+1); return SB; }
static void printFile(const sys::Path *err) { std::string ErrMsg; ErrMsg.clear(); MemoryBuffer *buf = MemoryBuffer::getFile(err->c_str(), &ErrMsg); errs().write(buf->getBufferStart(), buf->getBufferSize()); delete buf; }
bool TextInstrProfReader::hasFormat(const MemoryBuffer &Buffer) { // Verify that this really looks like plain ASCII text by checking a // 'reasonable' number of characters (up to profile magic size). size_t count = std::min(Buffer.getBufferSize(), sizeof(uint64_t)); StringRef buffer = Buffer.getBufferStart(); return count == 0 || std::all_of(buffer.begin(), buffer.begin() + count, [](char c) { return ::isprint(c) || ::isspace(c); }); }
bool RawInstrProfReader<IntPtrT>::hasFormat(const MemoryBuffer &DataBuffer) { if (DataBuffer.getBufferSize() < sizeof(uint64_t)) return false; uint64_t Magic = *reinterpret_cast<const uint64_t *>(DataBuffer.getBufferStart()); return RawInstrProf::getMagic<IntPtrT>() == Magic || sys::getSwappedBytes(RawInstrProf::getMagic<IntPtrT>()) == Magic; }
/// getMemBufferCopy - Open the specified memory range as a MemoryBuffer, /// copying the contents and taking ownership of it. This has no requirements /// on EndPtr[0]. MemoryBuffer *MemoryBuffer::getMemBufferCopy(StringRef InputData, StringRef BufferName) { MemoryBuffer *Buf = getNewUninitMemBuffer(InputData.size(), BufferName); if (!Buf) return 0; memcpy(const_cast<char*>(Buf->getBufferStart()), InputData.data(), InputData.size()); return Buf; }
/// Writes out bytes from \p FromFile, starting at \p NextToWrite and ending at /// \p WriteTo - 1. void InclusionRewriter::OutputContentUpTo(const MemoryBuffer &FromFile, unsigned &WriteFrom, unsigned WriteTo, StringRef EOL, int &Line, bool EnsureNewline) { if (WriteTo <= WriteFrom) return; OS.write(FromFile.getBufferStart() + WriteFrom, WriteTo - WriteFrom); // count lines manually, it's faster than getPresumedLoc() Line += std::count(FromFile.getBufferStart() + WriteFrom, FromFile.getBufferStart() + WriteTo, '\n'); if (EnsureNewline) { char LastChar = FromFile.getBufferStart()[WriteTo - 1]; if (LastChar != '\n' && LastChar != '\r') OS << EOL; } WriteFrom = WriteTo; }
bool IndexedInstrProfReader::hasFormat(const MemoryBuffer &DataBuffer) { if (DataBuffer.getBufferSize() < 8) return false; using namespace support; uint64_t Magic = endian::read<uint64_t, little, aligned>(DataBuffer.getBufferStart()); return Magic == IndexedInstrProf::Magic; }
/// Writes out bytes from \p FromFile, starting at \p NextToWrite and ending at /// \p WriteTo - 1. void InclusionRewriter::OutputContentUpTo(const MemoryBuffer &FromFile, unsigned &WriteFrom, unsigned WriteTo, StringRef LocalEOL, int &Line, bool EnsureNewline) { if (WriteTo <= WriteFrom) return; if (&FromFile == PredefinesBuffer) { // Ignore the #defines of the predefines buffer. WriteFrom = WriteTo; return; } // If we would output half of a line ending, advance one character to output // the whole line ending. All buffers are null terminated, so looking ahead // one byte is safe. if (LocalEOL.size() == 2 && LocalEOL[0] == (FromFile.getBufferStart() + WriteTo)[-1] && LocalEOL[1] == (FromFile.getBufferStart() + WriteTo)[0]) WriteTo++; StringRef TextToWrite(FromFile.getBufferStart() + WriteFrom, WriteTo - WriteFrom); if (MainEOL == LocalEOL) { OS << TextToWrite; // count lines manually, it's faster than getPresumedLoc() Line += TextToWrite.count(LocalEOL); if (EnsureNewline && !TextToWrite.endswith(LocalEOL)) OS << MainEOL; } else { // Output the file one line at a time, rewriting the line endings as we go. StringRef Rest = TextToWrite; while (!Rest.empty()) { StringRef LineText; std::tie(LineText, Rest) = Rest.split(LocalEOL); OS << LineText; Line++; if (!Rest.empty()) OS << MainEOL; } if (TextToWrite.endswith(LocalEOL) || EnsureNewline) OS << MainEOL; } WriteFrom = WriteTo; }
// Write one member out to the file. bool Archive::writeMember( const ArchiveMember& member, raw_fd_ostream& ARFile, std::string* ErrMsg ) { uint64_t filepos = ARFile.tell(); filepos -= 8; // Get the data and its size either from the // member's in-memory data or directly from the file. size_t fSize = member.getSize(); const char *data = (const char*)member.getData(); MemoryBuffer *mFile = 0; if (!data) { ErrorOr<std::unique_ptr<MemoryBuffer> > FileOrErr = MemoryBuffer::getFile(member.getPath()); if (!FileOrErr) { if (ErrMsg) *ErrMsg = FileOrErr.getError().message(); return true; } mFile = FileOrErr.get().release(); data = mFile->getBufferStart(); fSize = mFile->getBufferSize(); } int hdrSize = fSize; // Compute the fields of the header ArchiveMemberHeader Hdr; bool writeLongName = fillHeader(member,Hdr,hdrSize); // Write header to archive file ARFile.write((char*)&Hdr, sizeof(Hdr)); // Write the long filename if its long if (writeLongName) { StringRef Name = sys::path::filename(member.getPath()); ARFile.write(Name.data(), Name.size()); } // Write the (possibly compressed) member's content to the file. ARFile.write(data,fSize); // Make sure the member is an even length if ((ARFile.tell() & 1) == 1) ARFile << ARFILE_PAD; // Close the mapped file if it was opened delete mFile; return false; }
line_iterator::line_iterator(const MemoryBuffer &Buffer, char CommentMarker) : Buffer(Buffer.getBufferSize() ? &Buffer : nullptr), CommentMarker(CommentMarker), LineNumber(1), CurrentLine(Buffer.getBufferSize() ? Buffer.getBufferStart() : nullptr, 0) { // Ensure that if we are constructed on a non-empty memory buffer that it is // a null terminated buffer. if (Buffer.getBufferSize()) { assert(Buffer.getBufferEnd()[0] == '\0'); advance(); } }
/// GetMessage - Return an SMDiagnostic at the specified location with the /// specified string. /// /// @param Type - If non-null, the kind of message (e.g., "error") which is /// prefixed to the message. SMDiagnostic SourceMgr::GetMessage(SMLoc Loc, SourceMgr::DiagKind Kind, const Twine &Msg, ArrayRef<SMRange> Ranges) const { // First thing to do: find the current buffer containing the specified // location. int CurBuf = FindBufferContainingLoc(Loc); assert(CurBuf != -1 && "Invalid or unspecified location!"); MemoryBuffer *CurMB = getBufferInfo(CurBuf).Buffer; // Scan backward to find the start of the line. const char *LineStart = Loc.getPointer(); while (LineStart != CurMB->getBufferStart() && LineStart[-1] != '\n' && LineStart[-1] != '\r') --LineStart; // Get the end of the line. const char *LineEnd = Loc.getPointer(); while (LineEnd != CurMB->getBufferEnd() && LineEnd[0] != '\n' && LineEnd[0] != '\r') ++LineEnd; std::string LineStr(LineStart, LineEnd); // Convert any ranges to column ranges that only intersect the line of the // location. SmallVector<std::pair<unsigned, unsigned>, 4> ColRanges; for (unsigned i = 0, e = Ranges.size(); i != e; ++i) { SMRange R = Ranges[i]; if (!R.isValid()) continue; // If the line doesn't contain any part of the range, then ignore it. if (R.Start.getPointer() > LineEnd || R.End.getPointer() < LineStart) continue; // Ignore pieces of the range that go onto other lines. if (R.Start.getPointer() < LineStart) R.Start = SMLoc::getFromPointer(LineStart); if (R.End.getPointer() > LineEnd) R.End = SMLoc::getFromPointer(LineEnd); // Translate from SMLoc ranges to column ranges. ColRanges.push_back(std::make_pair(R.Start.getPointer()-LineStart, R.End.getPointer()-LineStart)); } return SMDiagnostic(*this, Loc, CurMB->getBufferIdentifier(), FindLineNumber(Loc, CurBuf), Loc.getPointer()-LineStart, Kind, Msg.str(), LineStr, ColRanges); }
ObjectImage *RuntimeDyldMachO::createObjectImageFromFile( std::unique_ptr<object::ObjectFile> ObjFile) { if (!ObjFile) return nullptr; MemoryBuffer *Buffer = MemoryBuffer::getMemBuffer(ObjFile->getData(), "", false); uint32_t magic = *((uint32_t *)Buffer->getBufferStart()); bool is64 = (magic == MachO::MH_MAGIC_64); assert((magic == MachO::MH_MAGIC_64 || magic == MachO::MH_MAGIC) && "Unrecognized Macho Magic"); return new MachOObjectImage(std::move(ObjFile), is64); }
bool Preprocessor::SetCodeCompletionPoint(const FileEntry *File, unsigned CompleteLine, unsigned CompleteColumn) { assert(File); assert(CompleteLine && CompleteColumn && "Starts from 1:1"); assert(!CodeCompletionFile && "Already set"); using llvm::MemoryBuffer; // Load the actual file's contents. bool Invalid = false; const MemoryBuffer *Buffer = SourceMgr.getMemoryBufferForFile(File, &Invalid); if (Invalid) return true; // Find the byte position of the truncation point. const char *Position = Buffer->getBufferStart(); for (unsigned Line = 1; Line < CompleteLine; ++Line) { for (; *Position; ++Position) { if (*Position != '\r' && *Position != '\n') continue; // Eat \r\n or \n\r as a single line. if ((Position[1] == '\r' || Position[1] == '\n') && Position[0] != Position[1]) ++Position; ++Position; break; } } Position += CompleteColumn - 1; // Insert '\0' at the code-completion point. if (Position < Buffer->getBufferEnd()) { CodeCompletionFile = File; CodeCompletionOffset = Position - Buffer->getBufferStart(); MemoryBuffer *NewBuffer = MemoryBuffer::getNewUninitMemBuffer(Buffer->getBufferSize() + 1, Buffer->getBufferIdentifier()); char *NewBuf = const_cast<char*>(NewBuffer->getBufferStart()); char *NewPos = std::copy(Buffer->getBufferStart(), Position, NewBuf); *NewPos = '\0'; std::copy(Position, Buffer->getBufferEnd(), NewPos+1); SourceMgr.overrideFileContents(File, NewBuffer); } return false; }
void ReadBundle(raw_fd_ostream &OS, MemoryBuffer &Input) final { // If the current section has size one, that means that the content we are // interested in is the file itself. Otherwise it is the content of the // section. // // TODO: Instead of copying the input file as is, deactivate the section // that is no longer needed. StringRef Content; CurrentSection->getContents(Content); if (Content.size() < 2) OS.write(Input.getBufferStart(), Input.getBufferSize()); else OS.write(Content.data(), Content.size()); }
// Look up one symbol in the symbol table and return a ModuleProvider for the // module that defines that symbol. ModuleProvider* Archive::findModuleDefiningSymbol(const std::string& symbol, std::string* ErrMsg) { SymTabType::iterator SI = symTab.find(symbol); if (SI == symTab.end()) return 0; // The symbol table was previously constructed assuming that the members were // written without the symbol table header. Because VBR encoding is used, the // values could not be adjusted to account for the offset of the symbol table // because that could affect the size of the symbol table due to VBR encoding. // We now have to account for this by adjusting the offset by the size of the // symbol table and its header. unsigned fileOffset = SI->second + // offset in symbol-table-less file firstFileOffset; // add offset to first "real" file in archive // See if the module is already loaded ModuleMap::iterator MI = modules.find(fileOffset); if (MI != modules.end()) return MI->second.first; // Module hasn't been loaded yet, we need to load it const char* modptr = base + fileOffset; ArchiveMember* mbr = parseMemberHeader(modptr, mapfile->getBufferEnd(), ErrMsg); if (!mbr) return 0; // Now, load the bitcode module to get the ModuleProvider std::string FullMemberName = archPath.str() + "(" + mbr->getPath().str() + ")"; MemoryBuffer *Buffer =MemoryBuffer::getNewMemBuffer(mbr->getSize(), FullMemberName.c_str()); memcpy((char*)Buffer->getBufferStart(), mbr->getData(), mbr->getSize()); ModuleProvider *mp = getBitcodeModuleProvider(Buffer, Context, ErrMsg); if (!mp) return 0; modules.insert(std::make_pair(fileOffset, std::make_pair(mp, mbr))); return mp; }
void LicenseInHeaderRule::run(const ast_matchers::MatchFinder::MatchResult& result) { const TranslationUnitDecl* translationUnitDeclaration = result.Nodes.getNodeAs<TranslationUnitDecl>("translationUnitDecl"); if (translationUnitDeclaration == nullptr) return; if (m_context.licenseTemplateLines.empty()) return; SourceManager& sourceManager = *result.SourceManager; FileID mainFileID = m_context.sourceLocationHelper.GetMainFileID(sourceManager); MemoryBuffer* buffer = sourceManager.getBuffer(mainFileID); const char* bufferChars = buffer->getBufferStart(); int bufferSize = buffer->getBufferSize(); if (bufferSize == 0) return; int bufferPos = 0; int lineNumber = 0; for (const auto& licenseLine : m_context.licenseTemplateLines) { ++lineNumber; StringRef line = GetNextBufferLine(bufferChars, bufferPos, bufferSize); bufferPos += line.size(); bufferPos += 1; // newline character if (line != licenseLine) { StringRef fileName = m_context.sourceLocationHelper.GetCleanFilename(mainFileID, sourceManager); m_context.outputPrinter->PrintRuleViolation( "license header", Severity::Style, boost::str(boost::format("File doesn't have proper license header; expected line was '%s'") % licenseLine), fileName, lineNumber); break; } } }
/// getLineAndColumn - Find the line and column number for the specified /// location in the specified file. This is not a fast method. std::pair<unsigned, unsigned> SourceMgr::getLineAndColumn(SMLoc Loc, int BufferID) const { if (BufferID == -1) BufferID = FindBufferContainingLoc(Loc); assert(BufferID != -1 && "Invalid Location!"); MemoryBuffer *Buff = getBufferInfo(BufferID).Buffer; // Count the number of \n's between the start of the file and the specified // location. unsigned LineNo = 1; const char *BufStart = Buff->getBufferStart(); const char *Ptr = BufStart; // If we have a line number cache, and if the query is to a later point in the // same file, start searching from the last query location. This optimizes // for the case when multiple diagnostics come out of one file in order. if (LineNoCacheTy *Cache = getCache(LineNoCache)) if (Cache->LastQueryBufferID == BufferID && Cache->LastQuery <= Loc.getPointer()) { Ptr = Cache->LastQuery; LineNo = Cache->LineNoOfQuery; } // Scan for the location being queried, keeping track of the number of lines // we see. for (; SMLoc::getFromPointer(Ptr) != Loc; ++Ptr) if (*Ptr == '\n') ++LineNo; // Allocate the line number cache if it doesn't exist. if (LineNoCache == 0) LineNoCache = new LineNoCacheTy(); // Update the line # cache. LineNoCacheTy &Cache = *getCache(LineNoCache); Cache.LastQueryBufferID = BufferID; Cache.LastQuery = Ptr; Cache.LineNoOfQuery = LineNo; size_t NewlineOffs = StringRef(BufStart, Ptr-BufStart).find_last_of("\n\r"); if (NewlineOffs == StringRef::npos) NewlineOffs = ~(size_t)0; return std::make_pair(LineNo, Ptr-BufStart-NewlineOffs); }
// Get all the bitcode modules from the archive bool Archive::getAllModules(std::vector<Module*>& Modules, std::string* ErrMessage) { for (iterator I=begin(), E=end(); I != E; ++I) { if (I->isBitcode()) { std::string FullMemberName = archPath.toString() + "(" + I->getPath().toString() + ")"; MemoryBuffer *Buffer = MemoryBuffer::getNewMemBuffer(I->getSize(), FullMemberName.c_str()); memcpy((char*)Buffer->getBufferStart(), I->getData(), I->getSize()); Module *M = ParseBitcodeFile(Buffer, ErrMessage); delete Buffer; if (!M) return true; Modules.push_back(M); } } return false; }
bool Archive::isBitcodeArchive() { // Make sure the symTab has been loaded. In most cases this should have been // done when the archive was constructed, but still, this is just in case. if (symTab.empty()) if (!loadSymbolTable(0)) return false; // Now that we know it's been loaded, return true // if it has a size if (symTab.size()) return true; // We still can't be sure it isn't a bitcode archive if (!loadArchive(0)) return false; std::vector<Module *> Modules; std::string ErrorMessage; // Scan the archive, trying to load a bitcode member. We only load one to // see if this works. for (iterator I = begin(), E = end(); I != E; ++I) { if (!I->isBitcode()) continue; std::string FullMemberName = archPath.str() + "(" + I->getPath().str() + ")"; MemoryBuffer *Buffer = MemoryBuffer::getNewMemBuffer(I->getSize(), FullMemberName.c_str()); memcpy((char*)Buffer->getBufferStart(), I->getData(), I->getSize()); Module *M = ParseBitcodeFile(Buffer, Context); delete Buffer; if (!M) return false; // Couldn't parse bitcode, not a bitcode archive. delete M; return true; } return false; }
/// Read bytecode from PCH file. Initialize TheModule and setup /// LTypes vector. void llvm_pch_read(const unsigned char *Buffer, unsigned Size) { std::string ModuleName = TheModule->getModuleIdentifier(); if (TheModule) delete TheModule; clearTargetBuiltinCache(); MemoryBuffer *MB = MemoryBuffer::getNewMemBuffer(Size, ModuleName.c_str()); memcpy((char*)MB->getBufferStart(), Buffer, Size); std::string ErrMsg; TheModule = ParseBitcodeFile(MB, &ErrMsg); delete MB; if (!TheModule) { cerr << "Error reading bytecodes from PCH file\n"; cerr << ErrMsg << "\n"; exit(1); } if (PerFunctionPasses || PerModulePasses || CodeGenPasses) { delete PerFunctionPasses; delete PerModulePasses; delete CodeGenPasses; // Don't run codegen, when we should output PCH if (!flag_pch_file) createOptimizationPasses(); else llvm_pch_write_init(); } // Read LLVM Types string table readLLVMTypesStringTable(); readLLVMValues(); flag_llvm_pch_read = 1; }
/// GetMessage - Return an SMDiagnostic at the specified location with the /// specified string. /// /// @param Type - If non-null, the kind of message (e.g., "error") which is /// prefixed to the message. SMDiagnostic SourceMgr::GetMessage(SMLoc Loc, const Twine &Msg, const char *Type, bool ShowLine) const { // First thing to do: find the current buffer containing the specified // location. int CurBuf = FindBufferContainingLoc(Loc); assert(CurBuf != -1 && "Invalid or unspecified location!"); MemoryBuffer *CurMB = getBufferInfo(CurBuf).Buffer; // Scan backward to find the start of the line. const char *LineStart = Loc.getPointer(); while (LineStart != CurMB->getBufferStart() && LineStart[-1] != '\n' && LineStart[-1] != '\r') --LineStart; std::string LineStr; if (ShowLine) { // Get the end of the line. const char *LineEnd = Loc.getPointer(); while (LineEnd != CurMB->getBufferEnd() && LineEnd[0] != '\n' && LineEnd[0] != '\r') ++LineEnd; LineStr = std::string(LineStart, LineEnd); } std::string PrintedMsg; raw_string_ostream OS(PrintedMsg); if (Type) OS << Type << ": "; OS << Msg; return SMDiagnostic(*this, Loc, CurMB->getBufferIdentifier(), FindLineNumber(Loc, CurBuf), Loc.getPointer()-LineStart, OS.str(), LineStr, ShowLine); }
/// AnalyzeBitcode - Analyze the bitcode file specified by InputFilename. static int AnalyzeBitcode() { // Read the input file. MemoryBuffer *Buffer; if (InputFilename == "-") Buffer = MemoryBuffer::getSTDIN(); else Buffer = MemoryBuffer::getFile(&InputFilename[0], InputFilename.size()); if (Buffer == 0) return Error("Error reading '" + InputFilename + "'."); if (Buffer->getBufferSize() & 3) return Error("Bitcode stream should be a multiple of 4 bytes in length"); unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart(); BitstreamReader Stream(BufPtr, BufPtr+Buffer->getBufferSize()); // Read the stream signature. char Signature[6]; Signature[0] = Stream.Read(8); Signature[1] = Stream.Read(8); Signature[2] = Stream.Read(4); Signature[3] = Stream.Read(4); Signature[4] = Stream.Read(4); Signature[5] = Stream.Read(4); // Autodetect the file contents, if it is one we know. CurStreamType = UnknownBitstream; if (Signature[0] == 'B' && Signature[1] == 'C' && Signature[2] == 0x0 && Signature[3] == 0xC && Signature[4] == 0xE && Signature[5] == 0xD) CurStreamType = LLVMIRBitstream; unsigned NumTopBlocks = 0; // Parse the top-level structure. We only allow blocks at the top-level. while (!Stream.AtEndOfStream()) { unsigned Code = Stream.ReadCode(); if (Code != bitc::ENTER_SUBBLOCK) return Error("Invalid record at top-level"); if (ParseBlock(Stream, 0)) return true; ++NumTopBlocks; } if (Dump) std::cerr << "\n\n"; uint64_t BufferSizeBits = Buffer->getBufferSize()*8; // Print a summary of the read file. std::cerr << "Summary of " << InputFilename << ":\n"; std::cerr << " Total size: "; PrintSize(BufferSizeBits); std::cerr << "\n"; std::cerr << " Stream type: "; switch (CurStreamType) { default: assert(0 && "Unknown bitstream type"); case UnknownBitstream: std::cerr << "unknown\n"; break; case LLVMIRBitstream: std::cerr << "LLVM IR\n"; break; } std::cerr << " # Toplevel Blocks: " << NumTopBlocks << "\n"; std::cerr << "\n"; // Emit per-block stats. std::cerr << "Per-block Summary:\n"; for (std::map<unsigned, PerBlockIDStats>::iterator I = BlockIDStats.begin(), E = BlockIDStats.end(); I != E; ++I) { std::cerr << " Block ID #" << I->first; if (const char *BlockName = GetBlockName(I->first)) std::cerr << " (" << BlockName << ")"; std::cerr << ":\n"; const PerBlockIDStats &Stats = I->second; std::cerr << " Num Instances: " << Stats.NumInstances << "\n"; std::cerr << " Total Size: "; PrintSize(Stats.NumBits); std::cerr << "\n"; std::cerr << " % of file: " << Stats.NumBits/(double)BufferSizeBits*100 << "\n"; if (Stats.NumInstances > 1) { std::cerr << " Average Size: "; PrintSize(Stats.NumBits/(double)Stats.NumInstances); std::cerr << "\n"; std::cerr << " Tot/Avg SubBlocks: " << Stats.NumSubBlocks << "/" << Stats.NumSubBlocks/(double)Stats.NumInstances << "\n"; std::cerr << " Tot/Avg Abbrevs: " << Stats.NumAbbrevs << "/" << Stats.NumAbbrevs/(double)Stats.NumInstances << "\n"; std::cerr << " Tot/Avg Records: " << Stats.NumRecords << "/" << Stats.NumRecords/(double)Stats.NumInstances << "\n"; } else { std::cerr << " Num SubBlocks: " << Stats.NumSubBlocks << "\n"; std::cerr << " Num Abbrevs: " << Stats.NumAbbrevs << "\n"; std::cerr << " Num Records: " << Stats.NumRecords << "\n"; } if (Stats.NumRecords) std::cerr << " % Abbrev Recs: " << (Stats.NumAbbreviatedRecords/ (double)Stats.NumRecords)*100 << "\n"; std::cerr << "\n"; // Print a histogram of the codes we see. if (!NoHistogram && !Stats.CodeFreq.empty()) { std::vector<std::pair<unsigned, unsigned> > FreqPairs; // <freq,code> for (unsigned i = 0, e = Stats.CodeFreq.size(); i != e; ++i) if (unsigned Freq = Stats.CodeFreq[i]) FreqPairs.push_back(std::make_pair(Freq, i)); std::stable_sort(FreqPairs.begin(), FreqPairs.end()); std::reverse(FreqPairs.begin(), FreqPairs.end()); std::cerr << "\tCode Histogram:\n"; for (unsigned i = 0, e = FreqPairs.size(); i != e; ++i) { std::cerr << "\t\t" << FreqPairs[i].first << "\t"; if (const char *CodeName = GetCodeName(FreqPairs[i].second, I->first)) std::cerr << CodeName << "\n"; else std::cerr << "UnknownCode" << FreqPairs[i].second << "\n"; } std::cerr << "\n"; } } return 0; }
bool SampleProfileReaderGCC::hasFormat(const MemoryBuffer &Buffer) { StringRef Magic(reinterpret_cast<const char *>(Buffer.getBufferStart())); return Magic == "adcg*704"; }
bool SampleProfileReaderBinary::hasFormat(const MemoryBuffer &Buffer) { const uint8_t *Data = reinterpret_cast<const uint8_t *>(Buffer.getBufferStart()); uint64_t Magic = decodeULEB128(Data); return Magic == SPMagic(); }
ErrorOr<unique_ptr<Executable>> parseExecutable(MemoryBuffer& executableCode) { auto start = reinterpret_cast<const uint8_t*>(executableCode.getBufferStart()); auto end = reinterpret_cast<const uint8_t*>(executableCode.getBufferEnd()); return Executable::parse(start, end); }