/// addDefinedSymbol - Add a defined symbol to the list.
void LTOModule::addDefinedSymbol(const GlobalValue *def, bool isFunction) {
  // ignore all llvm.* symbols
  if (def->getName().startswith("llvm."))
    return;

  // string is owned by _defines
  SmallString<64> Buffer;
  _mangler.getNameWithPrefix(Buffer, def, false);

  // set alignment part log2() can have rounding errors
  uint32_t align = def->getAlignment();
  uint32_t attr = align ? countTrailingZeros(def->getAlignment()) : 0;

  // set permissions part
  if (isFunction) {
    attr |= LTO_SYMBOL_PERMISSIONS_CODE;
  } else {
    const GlobalVariable *gv = dyn_cast<GlobalVariable>(def);
    if (gv && gv->isConstant())
      attr |= LTO_SYMBOL_PERMISSIONS_RODATA;
    else
      attr |= LTO_SYMBOL_PERMISSIONS_DATA;
  }

  // set definition part
  if (def->hasWeakLinkage() || def->hasLinkOnceLinkage() ||
      def->hasLinkerPrivateWeakLinkage())
    attr |= LTO_SYMBOL_DEFINITION_WEAK;
  else if (def->hasCommonLinkage())
    attr |= LTO_SYMBOL_DEFINITION_TENTATIVE;
  else
    attr |= LTO_SYMBOL_DEFINITION_REGULAR;

  // set scope part
  if (def->hasHiddenVisibility())
    attr |= LTO_SYMBOL_SCOPE_HIDDEN;
  else if (def->hasProtectedVisibility())
    attr |= LTO_SYMBOL_SCOPE_PROTECTED;
  else if (def->hasExternalLinkage() || def->hasWeakLinkage() ||
           def->hasLinkOnceLinkage() || def->hasCommonLinkage() ||
           def->hasLinkerPrivateWeakLinkage())
    attr |= LTO_SYMBOL_SCOPE_DEFAULT;
  else if (def->hasLinkOnceODRAutoHideLinkage())
    attr |= LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN;
  else
    attr |= LTO_SYMBOL_SCOPE_INTERNAL;

  StringSet::value_type &entry = _defines.GetOrCreateValue(Buffer);
  entry.setValue(1);

  // fill information structure
  NameAndAttributes info;
  StringRef Name = entry.getKey();
  info.name = Name.data();
  assert(info.name[Name.size()] == '\0');
  info.attributes = attr;
  info.isFunction = isFunction;
  info.symbol = def;

  // add to table of symbols
  _symbols.push_back(info);
}
Example #2
0
uint32_t zlib::crc32(StringRef Buffer) {
  return ::crc32(0, (const Bytef *)Buffer.data(), Buffer.size());
}
Example #3
0
/// ParseBlock - Read a block, updating statistics, etc.
static bool ParseBlock(BitstreamCursor &Stream, unsigned BlockID,
                       unsigned IndentLevel) {
  std::string Indent(IndentLevel*2, ' ');
  uint64_t BlockBitStart = Stream.GetCurrentBitNo();

  // Get the statistics for this BlockID.
  PerBlockIDStats &BlockStats = BlockIDStats[BlockID];

  BlockStats.NumInstances++;

  // BLOCKINFO is a special part of the stream.
  if (BlockID == bitc::BLOCKINFO_BLOCK_ID) {
    if (Dump) outs() << Indent << "<BLOCKINFO_BLOCK/>\n";
    if (Stream.ReadBlockInfoBlock())
      return Error("Malformed BlockInfoBlock");
    uint64_t BlockBitEnd = Stream.GetCurrentBitNo();
    BlockStats.NumBits += BlockBitEnd-BlockBitStart;
    return false;
  }

  unsigned NumWords = 0;
  if (Stream.EnterSubBlock(BlockID, &NumWords))
    return Error("Malformed block record");

  const char *BlockName = 0;
  if (Dump) {
    outs() << Indent << "<";
    if ((BlockName = GetBlockName(BlockID, *Stream.getBitStreamReader())))
      outs() << BlockName;
    else
      outs() << "UnknownBlock" << BlockID;

    if (NonSymbolic && BlockName)
      outs() << " BlockID=" << BlockID;

    outs() << " NumWords=" << NumWords
           << " BlockCodeSize=" << Stream.getAbbrevIDWidth() << ">\n";
  }

  SmallVector<uint64_t, 64> Record;

  // Read all the records for this block.
  while (1) {
    if (Stream.AtEndOfStream())
      return Error("Premature end of bitstream");

    uint64_t RecordStartBit = Stream.GetCurrentBitNo();

    BitstreamEntry Entry =
      Stream.advance(BitstreamCursor::AF_DontAutoprocessAbbrevs);
    
    switch (Entry.Kind) {
    case BitstreamEntry::Error:
      return Error("malformed bitcode file");
    case BitstreamEntry::EndBlock: {
      uint64_t BlockBitEnd = Stream.GetCurrentBitNo();
      BlockStats.NumBits += BlockBitEnd-BlockBitStart;
      if (Dump) {
        outs() << Indent << "</";
        if (BlockName)
          outs() << BlockName << ">\n";
        else
          outs() << "UnknownBlock" << BlockID << ">\n";
      }
      return false;
    }
        
    case BitstreamEntry::SubBlock: {
      uint64_t SubBlockBitStart = Stream.GetCurrentBitNo();
      if (ParseBlock(Stream, Entry.ID, IndentLevel+1))
        return true;
      ++BlockStats.NumSubBlocks;
      uint64_t SubBlockBitEnd = Stream.GetCurrentBitNo();
      
      // Don't include subblock sizes in the size of this block.
      BlockBitStart += SubBlockBitEnd-SubBlockBitStart;
      continue;
    }
    case BitstreamEntry::Record:
      // The interesting case.
      break;
    }

    if (Entry.ID == bitc::DEFINE_ABBREV) {
      Stream.ReadAbbrevRecord();
      ++BlockStats.NumAbbrevs;
      continue;
    }
    
    Record.clear();

    ++BlockStats.NumRecords;

    StringRef Blob;
    unsigned Code = Stream.readRecord(Entry.ID, Record, &Blob);

    // Increment the # occurrences of this code.
    if (BlockStats.CodeFreq.size() <= Code)
      BlockStats.CodeFreq.resize(Code+1);
    BlockStats.CodeFreq[Code].NumInstances++;
    BlockStats.CodeFreq[Code].TotalBits +=
      Stream.GetCurrentBitNo()-RecordStartBit;
    if (Entry.ID != bitc::UNABBREV_RECORD) {
      BlockStats.CodeFreq[Code].NumAbbrev++;
      ++BlockStats.NumAbbreviatedRecords;
    }

    if (Dump) {
      outs() << Indent << "  <";
      if (const char *CodeName =
            GetCodeName(Code, BlockID, *Stream.getBitStreamReader()))
        outs() << CodeName;
      else
        outs() << "UnknownCode" << Code;
      if (NonSymbolic &&
          GetCodeName(Code, BlockID, *Stream.getBitStreamReader()))
        outs() << " codeid=" << Code;
      if (Entry.ID != bitc::UNABBREV_RECORD)
        outs() << " abbrevid=" << Entry.ID;

      for (unsigned i = 0, e = Record.size(); i != e; ++i)
        outs() << " op" << i << "=" << (int64_t)Record[i];

      outs() << "/>";

      if (Blob.data()) {
        outs() << " blob data = ";
        bool BlobIsPrintable = true;
        for (unsigned i = 0, e = Blob.size(); i != e; ++i)
          if (!isprint(static_cast<unsigned char>(Blob[i]))) {
            BlobIsPrintable = false;
            break;
          }

        if (BlobIsPrintable)
          outs() << "'" << Blob << "'";
        else
          outs() << "unprintable, " << Blob.size() << " bytes.";
      }

      outs() << "\n";
    }
  }
}
Example #4
0
void RuntimeDyldMachO::processRelocationRef(unsigned SectionID,
                                            RelocationRef RelI,
                                            ObjectImage &Obj,
                                            ObjSectionToIDMap &ObjSectionToID,
                                            const SymbolTableMap &Symbols,
                                            StubMap &Stubs) {
  const ObjectFile *OF = Obj.getObjectFile();
  const MachOObjectFile *MachO = static_cast<const MachOObjectFile*>(OF);
  MachO::any_relocation_info RE= MachO->getRelocation(RelI.getRawDataRefImpl());

  uint32_t RelType = MachO->getAnyRelocationType(RE);

  // FIXME: Properly handle scattered relocations.
  //        For now, optimistically skip these: they can often be ignored, as
  //        the static linker will already have applied the relocation, and it
  //        only needs to be reapplied if symbols move relative to one another.
  //        Note: This will fail horribly where the relocations *do* need to be
  //        applied, but that was already the case.
  if (MachO->isRelocationScattered(RE))
    return;

  RelocationValueRef Value;
  SectionEntry &Section = Sections[SectionID];

  bool isExtern = MachO->getPlainRelocationExternal(RE);
  bool IsPCRel = MachO->getAnyRelocationPCRel(RE);
  unsigned Size = MachO->getAnyRelocationLength(RE);
  uint64_t Offset;
  RelI.getOffset(Offset);
  uint8_t *LocalAddress = Section.Address + Offset;
  unsigned NumBytes = 1 << Size;
  uint64_t Addend = 0;
  memcpy(&Addend, LocalAddress, NumBytes);

  if (isExtern) {
    // Obtain the symbol name which is referenced in the relocation
    symbol_iterator Symbol = RelI.getSymbol();
    StringRef TargetName;
    Symbol->getName(TargetName);
    // First search for the symbol in the local symbol table
    SymbolTableMap::const_iterator lsi = Symbols.find(TargetName.data());
    if (lsi != Symbols.end()) {
      Value.SectionID = lsi->second.first;
      Value.Addend = lsi->second.second + Addend;
    } else {
      // Search for the symbol in the global symbol table
      SymbolTableMap::const_iterator gsi = GlobalSymbolTable.find(TargetName.data());
      if (gsi != GlobalSymbolTable.end()) {
        Value.SectionID = gsi->second.first;
        Value.Addend = gsi->second.second + Addend;
      } else {
        Value.SymbolName = TargetName.data();
        Value.Addend = Addend;
      }
    }
  } else {
    SectionRef Sec = MachO->getRelocationSection(RE);
    Value.SectionID = findOrEmitSection(Obj, Sec, true, ObjSectionToID);
    uint64_t Addr;
    Sec.getAddress(Addr);
    Value.Addend = Addend - Addr;
  }

  if (Arch == Triple::x86_64 && (RelType == MachO::X86_64_RELOC_GOT ||
                                 RelType == MachO::X86_64_RELOC_GOT_LOAD)) {
    assert(IsPCRel);
    assert(Size == 2);
    StubMap::const_iterator i = Stubs.find(Value);
    uint8_t *Addr;
    if (i != Stubs.end()) {
      Addr = Section.Address + i->second;
    } else {
      Stubs[Value] = Section.StubOffset;
      uint8_t *GOTEntry = Section.Address + Section.StubOffset;
      RelocationEntry RE(SectionID, Section.StubOffset,
                         MachO::X86_64_RELOC_UNSIGNED, 0, false, 3);
      if (Value.SymbolName)
        addRelocationForSymbol(RE, Value.SymbolName);
      else
        addRelocationForSection(RE, Value.SectionID);
      Section.StubOffset += 8;
      Addr = GOTEntry;
    }
    resolveRelocation(Section, Offset, (uint64_t)Addr,
                      MachO::X86_64_RELOC_UNSIGNED, Value.Addend, true, 2);
  } else if (Arch == Triple::arm &&
             (RelType & 0xf) == MachO::ARM_RELOC_BR24) {
    // This is an ARM branch relocation, need to use a stub function.

    //  Look up for existing stub.
    StubMap::const_iterator i = Stubs.find(Value);
    if (i != Stubs.end())
      resolveRelocation(Section, Offset,
                        (uint64_t)Section.Address + i->second,
                        RelType, 0, IsPCRel, Size);
    else {
      // Create a new stub function.
      Stubs[Value] = Section.StubOffset;
      uint8_t *StubTargetAddr = createStubFunction(Section.Address +
                                                   Section.StubOffset);
      RelocationEntry RE(SectionID, StubTargetAddr - Section.Address,
                         MachO::GENERIC_RELOC_VANILLA, Value.Addend);
      if (Value.SymbolName)
        addRelocationForSymbol(RE, Value.SymbolName);
      else
        addRelocationForSection(RE, Value.SectionID);
      resolveRelocation(Section, Offset,
                        (uint64_t)Section.Address + Section.StubOffset,
                        RelType, 0, IsPCRel, Size);
      Section.StubOffset += getMaxStubSize();
    }
  } else {
    RelocationEntry RE(SectionID, Offset, RelType, Value.Addend,
                       IsPCRel, Size);
    if (Value.SymbolName)
      addRelocationForSymbol(RE, Value.SymbolName);
    else
      addRelocationForSection(RE, Value.SectionID);
  }
}
Example #5
0
static CXCodeCompleteResults *
clang_codeCompleteAt_Impl(CXTranslationUnit TU, const char *complete_filename,
                          unsigned complete_line, unsigned complete_column,
                          ArrayRef<CXUnsavedFile> unsaved_files,
                          unsigned options) {
  bool IncludeBriefComments = options & CXCodeComplete_IncludeBriefComments;

#ifdef UDP_CODE_COMPLETION_LOGGER
#ifdef UDP_CODE_COMPLETION_LOGGER_PORT
  const llvm::TimeRecord &StartTime =  llvm::TimeRecord::getCurrentTime();
#endif
#endif

  bool EnableLogging = getenv("LIBCLANG_CODE_COMPLETION_LOGGING") != nullptr;

  if (cxtu::isNotUsableTU(TU)) {
    LOG_BAD_TU(TU);
    return nullptr;
  }

  ASTUnit *AST = cxtu::getASTUnit(TU);
  if (!AST)
    return nullptr;

  CIndexer *CXXIdx = TU->CIdx;
  if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
    setThreadBackgroundPriority();

  ASTUnit::ConcurrencyCheck Check(*AST);

  // Perform the remapping of source files.
  SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;

  for (auto &UF : unsaved_files) {
    std::unique_ptr<llvm::MemoryBuffer> MB =
        llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
    RemappedFiles.push_back(std::make_pair(UF.Filename, MB.release()));
  }

  if (EnableLogging) {
    // FIXME: Add logging.
  }

  // Parse the resulting source file to find code-completion results.
  AllocatedCXCodeCompleteResults *Results = new AllocatedCXCodeCompleteResults(
      &AST->getFileManager());
  Results->Results = nullptr;
  Results->NumResults = 0;
  
  // Create a code-completion consumer to capture the results.
  CodeCompleteOptions Opts;
  Opts.IncludeBriefComments = IncludeBriefComments;
  CaptureCompletionResults Capture(Opts, *Results, &TU);

  // Perform completion.
  AST->CodeComplete(complete_filename, complete_line, complete_column,
                    RemappedFiles, (options & CXCodeComplete_IncludeMacros),
                    (options & CXCodeComplete_IncludeCodePatterns),
                    IncludeBriefComments, Capture,
                    CXXIdx->getPCHContainerOperations(), *Results->Diag,
                    Results->LangOpts, *Results->SourceMgr, *Results->FileMgr,
                    Results->Diagnostics, Results->TemporaryBuffers);

  Results->DiagnosticsWrappers.resize(Results->Diagnostics.size());

  // Keep a reference to the allocator used for cached global completions, so
  // that we can be sure that the memory used by our code completion strings
  // doesn't get freed due to subsequent reparses (while the code completion
  // results are still active).
  Results->CachedCompletionAllocator = AST->getCachedCompletionAllocator();

  

#ifdef UDP_CODE_COMPLETION_LOGGER
#ifdef UDP_CODE_COMPLETION_LOGGER_PORT
  const llvm::TimeRecord &EndTime =  llvm::TimeRecord::getCurrentTime();
  SmallString<256> LogResult;
  llvm::raw_svector_ostream os(LogResult);

  // Figure out the language and whether or not it uses PCH.
  const char *lang = 0;
  bool usesPCH = false;

  for (std::vector<const char*>::iterator I = argv.begin(), E = argv.end();
       I != E; ++I) {
    if (*I == 0)
      continue;
    if (strcmp(*I, "-x") == 0) {
      if (I + 1 != E) {
        lang = *(++I);
        continue;
      }
    }
    else if (strcmp(*I, "-include") == 0) {
      if (I+1 != E) {
        const char *arg = *(++I);
        SmallString<512> pchName;
        {
          llvm::raw_svector_ostream os(pchName);
          os << arg << ".pth";
        }
        pchName.push_back('\0');
        struct stat stat_results;
        if (stat(pchName.str().c_str(), &stat_results) == 0)
          usesPCH = true;
        continue;
      }
    }
  }

  os << "{ ";
  os << "\"wall\": " << (EndTime.getWallTime() - StartTime.getWallTime());
  os << ", \"numRes\": " << Results->NumResults;
  os << ", \"diags\": " << Results->Diagnostics.size();
  os << ", \"pch\": " << (usesPCH ? "true" : "false");
  os << ", \"lang\": \"" << (lang ? lang : "<unknown>") << '"';
  const char *name = getlogin();
  os << ", \"user\": \"" << (name ? name : "unknown") << '"';
  os << ", \"clangVer\": \"" << getClangFullVersion() << '"';
  os << " }";

  StringRef res = os.str();
  if (res.size() > 0) {
    do {
      // Setup the UDP socket.
      struct sockaddr_in servaddr;
      bzero(&servaddr, sizeof(servaddr));
      servaddr.sin_family = AF_INET;
      servaddr.sin_port = htons(UDP_CODE_COMPLETION_LOGGER_PORT);
      if (inet_pton(AF_INET, UDP_CODE_COMPLETION_LOGGER,
                    &servaddr.sin_addr) <= 0)
        break;

      int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
      if (sockfd < 0)
        break;

      sendto(sockfd, res.data(), res.size(), 0,
             (struct sockaddr *)&servaddr, sizeof(servaddr));
      close(sockfd);
    }
    while (false);
  }
#endif
#endif
  return Results;
}
Example #6
0
/// Mangle this entity as a std::string.
std::string LinkEntity::mangleAsString() const {
  IRGenMangler mangler;
  switch (getKind()) {
    case Kind::DispatchThunk:
      return mangler.mangleEntity(getDecl(), /*isCurried=*/false,
                                  ASTMangler::SymbolKind::SwiftDispatchThunk);

    case Kind::DispatchThunkInitializer:
      return mangler.mangleConstructorEntity(
          cast<ConstructorDecl>(getDecl()),
          /*isAllocating=*/false,
          /*isCurried=*/false,
          ASTMangler::SymbolKind::SwiftDispatchThunk);

    case Kind::DispatchThunkAllocator:
      return mangler.mangleConstructorEntity(
          cast<ConstructorDecl>(getDecl()),
          /*isAllocating=*/true,
          /*isCurried=*/false,
          ASTMangler::SymbolKind::SwiftDispatchThunk);

    case Kind::ValueWitness:
      return mangler.mangleValueWitness(getType(), getValueWitness());

    case Kind::ValueWitnessTable:
      return mangler.mangleValueWitnessTable(getType());

    case Kind::TypeMetadataAccessFunction:
      return mangler.mangleTypeMetadataAccessFunction(getType());

    case Kind::TypeMetadataLazyCacheVariable:
      return mangler.mangleTypeMetadataLazyCacheVariable(getType());

    case Kind::TypeMetadataInstantiationCache:
      return mangler.mangleTypeMetadataInstantiationCache(
                                              cast<NominalTypeDecl>(getDecl()));

    case Kind::TypeMetadataInstantiationFunction:
      return mangler.mangleTypeMetadataInstantiationFunction(
                                              cast<NominalTypeDecl>(getDecl()));

    case Kind::TypeMetadataInPlaceInitializationCache:
      return mangler.mangleTypeMetadataInPlaceInitializationCache(
                                              cast<NominalTypeDecl>(getDecl()));

    case Kind::TypeMetadataCompletionFunction:
      return mangler.mangleTypeMetadataCompletionFunction(
                                              cast<NominalTypeDecl>(getDecl()));

    case Kind::TypeMetadata:
      switch (getMetadataAddress()) {
        case TypeMetadataAddress::FullMetadata:
          return mangler.mangleTypeFullMetadataFull(getType());
        case TypeMetadataAddress::AddressPoint:
          return mangler.mangleTypeMetadataFull(getType());
      }
      llvm_unreachable("invalid metadata address");

    case Kind::TypeMetadataPattern:
      return mangler.mangleTypeMetadataPattern(
                                          cast<NominalTypeDecl>(getDecl()));

    case Kind::ForeignTypeMetadataCandidate:
      return mangler.mangleTypeMetadataFull(getType());

    case Kind::SwiftMetaclassStub:
      return mangler.mangleClassMetaClass(cast<ClassDecl>(getDecl()));

    case Kind::ClassMetadataBaseOffset:               // class metadata base offset
      return mangler.mangleClassMetadataBaseOffset(cast<ClassDecl>(getDecl()));

    case Kind::NominalTypeDescriptor:
      return mangler.mangleNominalTypeDescriptor(
                                          cast<NominalTypeDecl>(getDecl()));

    case Kind::PropertyDescriptor:
      return mangler.manglePropertyDescriptor(
                                          cast<AbstractStorageDecl>(getDecl()));

    case Kind::ModuleDescriptor:
      return mangler.mangleModuleDescriptor(cast<ModuleDecl>(getDecl()));
  
    case Kind::ExtensionDescriptor:
      return mangler.mangleExtensionDescriptor(getExtension());
    
    case Kind::AnonymousDescriptor:
      return mangler.mangleAnonymousDescriptor(getDeclContext());

    case Kind::ProtocolDescriptor:
      return mangler.mangleProtocolDescriptor(cast<ProtocolDecl>(getDecl()));

    case Kind::ProtocolConformanceDescriptor:
      return mangler.mangleProtocolConformanceDescriptor(
                     cast<NormalProtocolConformance>(getProtocolConformance()));

    case Kind::EnumCase:
      return mangler.mangleEnumCase(getDecl());

    case Kind::FieldOffset:
      return mangler.mangleFieldOffset(getDecl());

    case Kind::DirectProtocolWitnessTable:
      return mangler.mangleDirectProtocolWitnessTable(getProtocolConformance());

    case Kind::GenericProtocolWitnessTableCache:
      return mangler.mangleGenericProtocolWitnessTableCache(
                                                      getProtocolConformance());

    case Kind::GenericProtocolWitnessTableInstantiationFunction:
      return mangler.mangleGenericProtocolWitnessTableInstantiationFunction(
                                                      getProtocolConformance());

    case Kind::ResilientProtocolWitnessTable:
      return mangler.mangleResilientProtocolWitnessTable(getProtocolConformance());

    case Kind::ProtocolWitnessTableAccessFunction:
      return mangler.mangleProtocolWitnessTableAccessFunction(
                                                      getProtocolConformance());

    case Kind::ProtocolWitnessTablePattern:
      return mangler.mangleProtocolWitnessTablePattern(getProtocolConformance());

    case Kind::ProtocolWitnessTableLazyAccessFunction:
      return mangler.mangleProtocolWitnessTableLazyAccessFunction(getType(),
                                                      getProtocolConformance());

    case Kind::ProtocolWitnessTableLazyCacheVariable:
      return mangler.mangleProtocolWitnessTableLazyCacheVariable(getType(),
                                                      getProtocolConformance());

    case Kind::AssociatedTypeMetadataAccessFunction:
      return mangler.mangleAssociatedTypeMetadataAccessFunction(
                  getProtocolConformance(), getAssociatedType()->getNameStr());

    case Kind::AssociatedTypeWitnessTableAccessFunction: {
      auto assocConf = getAssociatedConformance();
      return mangler.mangleAssociatedTypeWitnessTableAccessFunction(
                  getProtocolConformance(), assocConf.first, assocConf.second);
    }

    case Kind::CoroutineContinuationPrototype:
      return mangler.mangleCoroutineContinuationPrototype(
                                              cast<SILFunctionType>(getType()));

      // An Objective-C class reference reference. The symbol is private, so
      // the mangling is unimportant; it should just be readable in LLVM IR.
    case Kind::ObjCClassRef: {
      llvm::SmallString<64> tempBuffer;
      StringRef name = cast<ClassDecl>(getDecl())->getObjCRuntimeName(tempBuffer);
      std::string Result("\01l_OBJC_CLASS_REF_$_");
      Result.append(name.data(), name.size());
      return Result;
    }

      // An Objective-C class reference;  not a swift mangling.
    case Kind::ObjCClass: {
      llvm::SmallString<64> TempBuffer;
      StringRef Name = cast<ClassDecl>(getDecl())->getObjCRuntimeName(TempBuffer);
      std::string Result("OBJC_CLASS_$_");
      Result.append(Name.data(), Name.size());
      return Result;
    }

      // An Objective-C metaclass reference;  not a swift mangling.
    case Kind::ObjCMetaclass: {
      llvm::SmallString<64> TempBuffer;
      StringRef Name = cast<ClassDecl>(getDecl())->getObjCRuntimeName(TempBuffer);
      std::string Result("OBJC_METACLASS_$_");
      Result.append(Name.data(), Name.size());
      return Result;
    }

    case Kind::SILFunction:
      return getSILFunction()->getName();
    case Kind::SILGlobalVariable:
      return getSILGlobalVariable()->getName();

    case Kind::ReflectionBuiltinDescriptor:
      return mangler.mangleReflectionBuiltinDescriptor(getType());
    case Kind::ReflectionFieldDescriptor:
      return mangler.mangleReflectionFieldDescriptor(getType());
    case Kind::ReflectionAssociatedTypeDescriptor:
      return mangler.mangleReflectionAssociatedTypeDescriptor(
                                                      getProtocolConformance());
  }
  llvm_unreachable("bad entity kind!");
}
Example #7
0
static void create_PRUNTIME_FUNCTION(uint8_t *Code, size_t Size, StringRef fnname,
        uint8_t *Section, size_t Allocated, uint8_t *UnwindData)
{
    DWORD mod_size = 0;
#if defined(_CPU_X86_64_)
#if !defined(USE_MCJIT)
    uint8_t *catchjmp = Section+Allocated;
    UnwindData = (uint8_t*)(((uintptr_t)catchjmp+12+3)&~(uintptr_t)3);
    if (!catchjmp[0]) {
        catchjmp[0] = 0x48;
        catchjmp[1] = 0xb8; // mov RAX, QWORD PTR [...]
        *(uint64_t*)(&catchjmp[2]) = (uint64_t)&_seh_exception_handler;
        catchjmp[10] = 0xff;
        catchjmp[11] = 0xe0; // jmp RAX
        UnwindData[0] = 0x09; // version info, UNW_FLAG_EHANDLER
        UnwindData[1] = 4;    // size of prolog (bytes)
        UnwindData[2] = 2;    // count of unwind codes (slots)
        UnwindData[3] = 0x05; // frame register (rbp) = rsp
        UnwindData[4] = 4;    // second instruction
        UnwindData[5] = 0x03; // mov RBP, RSP
        UnwindData[6] = 1;    // first instruction
        UnwindData[7] = 0x50; // push RBP
        *(DWORD*)&UnwindData[8] = (DWORD)(catchjmp - Section); // relative location of catchjmp
        mod_size = (DWORD)Allocated+48;
    }
    PRUNTIME_FUNCTION tbl = (PRUNTIME_FUNCTION)(UnwindData+12);
#else
    PRUNTIME_FUNCTION tbl = (PRUNTIME_FUNCTION)malloc(sizeof(RUNTIME_FUNCTION));
#endif
    tbl->BeginAddress = (DWORD)(Code - Section);
    tbl->EndAddress = (DWORD)(Code - Section + Size);
    tbl->UnwindData = (DWORD)(UnwindData - Section);
#else // defined(_CPU_X86_64_)
    Section += (uintptr_t)Code;
    mod_size = Size;
#endif
    if (0) {
        assert(!jl_in_stackwalk);
        jl_in_stackwalk = 1;
        if (mod_size && !SymLoadModuleEx(GetCurrentProcess(), NULL, NULL, NULL, (DWORD64)Section, mod_size, NULL, SLMFLAG_VIRTUAL)) {
#if defined(_CPU_X86_64_) && !defined(USE_MCJIT)
            catchjmp[0] = 0;
#endif
            static int warned = 0;
            if (!warned) {
                jl_printf(JL_STDERR, "WARNING: failed to insert module info for backtrace: %lu\n", GetLastError());
                warned = 1;
            }
        }
        else {
            size_t len = fnname.size()+1;
            if (len > MAX_SYM_NAME)
                len = MAX_SYM_NAME;
            char *name = (char*)alloca(len);
            memcpy(name, fnname.data(), len-1);
            name[len-1] = 0;
            if (!SymAddSymbol(GetCurrentProcess(), (ULONG64)Section, name,
                        (DWORD64)Code, (DWORD)Size, 0)) {
                jl_printf(JL_STDERR, "WARNING: failed to insert function name %s into debug info: %lu\n", name, GetLastError());
            }
        }
        jl_in_stackwalk = 0;
    }
#if defined(_CPU_X86_64_)
    if (!RtlAddFunctionTable(tbl, 1, (DWORD64)Section)) {
        static int warned = 0;
        if (!warned) {
            jl_printf(JL_STDERR, "WARNING: failed to insert function stack unwind info: %lu\n", GetLastError());
            warned = 1;
        }
    }
#endif
}
Example #8
0
bool DWARFFormValue::extractValue(DataExtractor data, uint32_t *offset_ptr,
                                  const DWARFUnit *cu) {
  bool indirect = false;
  bool is_block = false;
  Value.data = nullptr;
  // Read the value for the form into value and follow and DW_FORM_indirect
  // instances we run into
  do {
    indirect = false;
    switch (Form) {
    case DW_FORM_addr:
    case DW_FORM_ref_addr: {
      if (!cu)
        return false;
      uint16_t AddrSize =
          (Form == DW_FORM_addr)
              ? cu->getAddressByteSize()
              : getRefAddrSize(cu->getAddressByteSize(), cu->getVersion());
      RelocAddrMap::const_iterator AI = cu->getRelocMap()->find(*offset_ptr);
      if (AI != cu->getRelocMap()->end()) {
        const std::pair<uint8_t, int64_t> &R = AI->second;
        Value.uval = data.getUnsigned(offset_ptr, AddrSize) + R.second;
      } else
        Value.uval = data.getUnsigned(offset_ptr, AddrSize);
      break;
    }
    case DW_FORM_exprloc:
    case DW_FORM_block:
      Value.uval = data.getULEB128(offset_ptr);
      is_block = true;
      break;
    case DW_FORM_block1:
      Value.uval = data.getU8(offset_ptr);
      is_block = true;
      break;
    case DW_FORM_block2:
      Value.uval = data.getU16(offset_ptr);
      is_block = true;
      break;
    case DW_FORM_block4:
      Value.uval = data.getU32(offset_ptr);
      is_block = true;
      break;
    case DW_FORM_data1:
    case DW_FORM_ref1:
    case DW_FORM_flag:
      Value.uval = data.getU8(offset_ptr);
      break;
    case DW_FORM_data2:
    case DW_FORM_ref2:
      Value.uval = data.getU16(offset_ptr);
      break;
    case DW_FORM_data4:
    case DW_FORM_ref4: {
      Value.uval = data.getU32(offset_ptr);
      if (!cu)
        break;
      RelocAddrMap::const_iterator AI = cu->getRelocMap()->find(*offset_ptr-4);
      if (AI != cu->getRelocMap()->end())
        Value.uval += AI->second.second;
      break;
    }
    case DW_FORM_data8:
    case DW_FORM_ref8:
      Value.uval = data.getU64(offset_ptr);
      break;
    case DW_FORM_sdata:
      Value.sval = data.getSLEB128(offset_ptr);
      break;
    case DW_FORM_strp: {
      Value.uval = data.getU32(offset_ptr);
      if (!cu)
        break;
      RelocAddrMap::const_iterator AI = cu->getRelocMap()->find(*offset_ptr-4);
      if (AI != cu->getRelocMap()->end())
        Value.uval += AI->second.second;
      break;
    }
    case DW_FORM_udata:
    case DW_FORM_ref_udata:
      Value.uval = data.getULEB128(offset_ptr);
      break;
    case DW_FORM_string:
      Value.cstr = data.getCStr(offset_ptr);
      break;
    case DW_FORM_indirect:
      Form = data.getULEB128(offset_ptr);
      indirect = true;
      break;
    case DW_FORM_sec_offset: {
      // FIXME: This is 64-bit for DWARF64.
      Value.uval = data.getU32(offset_ptr);
      if (!cu)
        break;
      RelocAddrMap::const_iterator AI = cu->getRelocMap()->find(*offset_ptr-4);
      if (AI != cu->getRelocMap()->end())
        Value.uval +=  AI->second.second;
      break;
    }
    case DW_FORM_flag_present:
      Value.uval = 1;
      break;
    case DW_FORM_ref_sig8:
      Value.uval = data.getU64(offset_ptr);
      break;
    case DW_FORM_GNU_addr_index:
    case DW_FORM_GNU_str_index:
      Value.uval = data.getULEB128(offset_ptr);
      break;
    default:
      return false;
    }
  } while (indirect);

  if (is_block) {
    StringRef str = data.getData().substr(*offset_ptr, Value.uval);
    Value.data = nullptr;
    if (!str.empty()) {
      Value.data = reinterpret_cast<const uint8_t *>(str.data());
      *offset_ptr += Value.uval;
    }
  }

  return true;
}
Example #9
0
static void DisassembleInputMachO2(StringRef Filename,
                                   MachOObjectFile *MachOOF) {
  const Target *TheTarget = GetTarget(MachOOF);
  if (!TheTarget) {
    // GetTarget prints out stuff.
    return;
  }
  OwningPtr<const MCInstrInfo> InstrInfo(TheTarget->createMCInstrInfo());
  OwningPtr<MCInstrAnalysis>
    InstrAnalysis(TheTarget->createMCInstrAnalysis(InstrInfo.get()));

  // Set up disassembler.
  OwningPtr<const MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName));
  OwningPtr<const MCAsmInfo> AsmInfo(
      TheTarget->createMCAsmInfo(*MRI, TripleName));
  OwningPtr<const MCSubtargetInfo>
    STI(TheTarget->createMCSubtargetInfo(TripleName, "", ""));
  OwningPtr<const MCDisassembler> DisAsm(TheTarget->createMCDisassembler(*STI));
  int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
  OwningPtr<MCInstPrinter>
    IP(TheTarget->createMCInstPrinter(AsmPrinterVariant, *AsmInfo, *InstrInfo,
                                      *MRI, *STI));

  if (!InstrAnalysis || !AsmInfo || !STI || !DisAsm || !IP) {
    errs() << "error: couldn't initialize disassembler for target "
           << TripleName << '\n';
    return;
  }

  outs() << '\n' << Filename << ":\n\n";

  MachO::mach_header Header = MachOOF->getHeader();

  // FIXME: FoundFns isn't used anymore. Using symbols/LC_FUNCTION_STARTS to
  // determine function locations will eventually go in MCObjectDisassembler.
  // FIXME: Using the -cfg command line option, this code used to be able to
  // annotate relocations with the referenced symbol's name, and if this was
  // inside a __[cf]string section, the data it points to. This is now replaced
  // by the upcoming MCSymbolizer, which needs the appropriate setup done above.
  std::vector<SectionRef> Sections;
  std::vector<SymbolRef> Symbols;
  SmallVector<uint64_t, 8> FoundFns;
  uint64_t BaseSegmentAddress;

  getSectionsAndSymbols(Header, MachOOF, Sections, Symbols, FoundFns,
                        BaseSegmentAddress);

  // Sort the symbols by address, just in case they didn't come in that way.
  std::sort(Symbols.begin(), Symbols.end(), SymbolSorter());

  // Build a data in code table that is sorted on by the address of each entry.
  uint64_t BaseAddress = 0;
  if (Header.filetype == MachO::MH_OBJECT)
    Sections[0].getAddress(BaseAddress);
  else
    BaseAddress = BaseSegmentAddress;
  DiceTable Dices;
  for (dice_iterator DI = MachOOF->begin_dices(), DE = MachOOF->end_dices();
       DI != DE; ++DI) {
    uint32_t Offset;
    DI->getOffset(Offset);
    Dices.push_back(std::make_pair(BaseAddress + Offset, *DI));
  }
  array_pod_sort(Dices.begin(), Dices.end());

#ifndef NDEBUG
  raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls();
#else
  raw_ostream &DebugOut = nulls();
#endif

  OwningPtr<DIContext> diContext;
  ObjectFile *DbgObj = MachOOF;
  // Try to find debug info and set up the DIContext for it.
  if (UseDbg) {
    // A separate DSym file path was specified, parse it as a macho file,
    // get the sections and supply it to the section name parsing machinery.
    if (!DSYMFile.empty()) {
      OwningPtr<MemoryBuffer> Buf;
      if (error_code ec = MemoryBuffer::getFileOrSTDIN(DSYMFile, Buf)) {
        errs() << "llvm-objdump: " << Filename << ": " << ec.message() << '\n';
        return;
      }
      DbgObj = ObjectFile::createMachOObjectFile(Buf.take()).get();
    }

    // Setup the DIContext
    diContext.reset(DIContext::getDWARFContext(DbgObj));
  }

  for (unsigned SectIdx = 0; SectIdx != Sections.size(); SectIdx++) {

    bool SectIsText = false;
    Sections[SectIdx].isText(SectIsText);
    if (SectIsText == false)
      continue;

    StringRef SectName;
    if (Sections[SectIdx].getName(SectName) ||
        SectName != "__text")
      continue; // Skip non-text sections

    DataRefImpl DR = Sections[SectIdx].getRawDataRefImpl();

    StringRef SegmentName = MachOOF->getSectionFinalSegmentName(DR);
    if (SegmentName != "__TEXT")
      continue;

    StringRef Bytes;
    Sections[SectIdx].getContents(Bytes);
    StringRefMemoryObject memoryObject(Bytes);
    bool symbolTableWorked = false;

    // Parse relocations.
    std::vector<std::pair<uint64_t, SymbolRef> > Relocs;
    for (relocation_iterator RI = Sections[SectIdx].relocation_begin(),
                             RE = Sections[SectIdx].relocation_end();
         RI != RE; ++RI) {
      uint64_t RelocOffset, SectionAddress;
      RI->getOffset(RelocOffset);
      Sections[SectIdx].getAddress(SectionAddress);
      RelocOffset -= SectionAddress;

      symbol_iterator RelocSym = RI->getSymbol();

      Relocs.push_back(std::make_pair(RelocOffset, *RelocSym));
    }
    array_pod_sort(Relocs.begin(), Relocs.end());

    // Disassemble symbol by symbol.
    for (unsigned SymIdx = 0; SymIdx != Symbols.size(); SymIdx++) {
      StringRef SymName;
      Symbols[SymIdx].getName(SymName);

      SymbolRef::Type ST;
      Symbols[SymIdx].getType(ST);
      if (ST != SymbolRef::ST_Function)
        continue;

      // Make sure the symbol is defined in this section.
      bool containsSym = false;
      Sections[SectIdx].containsSymbol(Symbols[SymIdx], containsSym);
      if (!containsSym)
        continue;

      // Start at the address of the symbol relative to the section's address.
      uint64_t SectionAddress = 0;
      uint64_t Start = 0;
      Sections[SectIdx].getAddress(SectionAddress);
      Symbols[SymIdx].getAddress(Start);
      Start -= SectionAddress;

      // Stop disassembling either at the beginning of the next symbol or at
      // the end of the section.
      bool containsNextSym = false;
      uint64_t NextSym = 0;
      uint64_t NextSymIdx = SymIdx+1;
      while (Symbols.size() > NextSymIdx) {
        SymbolRef::Type NextSymType;
        Symbols[NextSymIdx].getType(NextSymType);
        if (NextSymType == SymbolRef::ST_Function) {
          Sections[SectIdx].containsSymbol(Symbols[NextSymIdx],
                                           containsNextSym);
          Symbols[NextSymIdx].getAddress(NextSym);
          NextSym -= SectionAddress;
          break;
        }
        ++NextSymIdx;
      }

      uint64_t SectSize;
      Sections[SectIdx].getSize(SectSize);
      uint64_t End = containsNextSym ?  NextSym : SectSize;
      uint64_t Size;

      symbolTableWorked = true;

      outs() << SymName << ":\n";
      DILineInfo lastLine;
      for (uint64_t Index = Start; Index < End; Index += Size) {
        MCInst Inst;

        uint64_t SectAddress = 0;
        Sections[SectIdx].getAddress(SectAddress);
        outs() << format("%8" PRIx64 ":\t", SectAddress + Index);

        // Check the data in code table here to see if this is data not an
        // instruction to be disassembled.
        DiceTable Dice;
        Dice.push_back(std::make_pair(SectAddress + Index, DiceRef()));
        dice_table_iterator DTI = std::search(Dices.begin(), Dices.end(),
                                              Dice.begin(), Dice.end(),
                                              compareDiceTableEntries);
        if (DTI != Dices.end()){
          uint16_t Length;
          DTI->second.getLength(Length);
          DumpBytes(StringRef(Bytes.data() + Index, Length));
          uint16_t Kind;
          DTI->second.getKind(Kind);
          DumpDataInCode(Bytes.data() + Index, Length, Kind);
          continue;
        }

        if (DisAsm->getInstruction(Inst, Size, memoryObject, Index,
                                   DebugOut, nulls())) {
          DumpBytes(StringRef(Bytes.data() + Index, Size));
          IP->printInst(&Inst, outs(), "");

          // Print debug info.
          if (diContext) {
            DILineInfo dli =
              diContext->getLineInfoForAddress(SectAddress + Index);
            // Print valid line info if it changed.
            if (dli != lastLine && dli.getLine() != 0)
              outs() << "\t## " << dli.getFileName() << ':'
                << dli.getLine() << ':' << dli.getColumn();
            lastLine = dli;
          }
          outs() << "\n";
        } else {
          errs() << "llvm-objdump: warning: invalid instruction encoding\n";
          if (Size == 0)
            Size = 1; // skip illegible bytes
        }
      }
    }
    if (!symbolTableWorked) {
      // Reading the symbol table didn't work, disassemble the whole section. 
      uint64_t SectAddress;
      Sections[SectIdx].getAddress(SectAddress);
      uint64_t SectSize;
      Sections[SectIdx].getSize(SectSize);
      uint64_t InstSize;
      for (uint64_t Index = 0; Index < SectSize; Index += InstSize) {
        MCInst Inst;

        if (DisAsm->getInstruction(Inst, InstSize, memoryObject, Index,
                                   DebugOut, nulls())) {
          outs() << format("%8" PRIx64 ":\t", SectAddress + Index);
          DumpBytes(StringRef(Bytes.data() + Index, InstSize));
          IP->printInst(&Inst, outs(), "");
          outs() << "\n";
        } else {
          errs() << "llvm-objdump: warning: invalid instruction encoding\n";
          if (InstSize == 0)
            InstSize = 1; // skip illegible bytes
        }
      }
    }
  }
}
static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H,
                                                  const char *&Beg,
                                                  const char *E,
                                                  unsigned &argIndex,
                                                  const LangOptions &LO,
                                                  const TargetInfo &Target,
                                                  bool Warn,
                                                  bool isFreeBSDKPrintf) {

  using namespace clang::analyze_format_string;
  using namespace clang::analyze_printf;

  const char *I = Beg;
  const char *Start = nullptr;
  UpdateOnReturn <const char*> UpdateBeg(Beg, I);

  // Look for a '%' character that indicates the start of a format specifier.
  for ( ; I != E ; ++I) {
    char c = *I;
    if (c == '\0') {
      // Detect spurious null characters, which are likely errors.
      H.HandleNullChar(I);
      return true;
    }
    if (c == '%') {
      Start = I++;  // Record the start of the format specifier.
      break;
    }
  }

  // No format specifier found?
  if (!Start)
    return false;

  if (I == E) {
    // No more characters left?
    if (Warn)
      H.HandleIncompleteSpecifier(Start, E - Start);
    return true;
  }

  PrintfSpecifier FS;
  if (ParseArgPosition(H, FS, Start, I, E))
    return true;

  if (I == E) {
    // No more characters left?
    if (Warn)
      H.HandleIncompleteSpecifier(Start, E - Start);
    return true;
  }

  if (*I == '{') {
    ++I;
    unsigned char PrivacyFlags = 0;
    StringRef MatchedStr;

    do {
      StringRef Str(I, E - I);
      std::string Match = "^[\t\n\v\f\r ]*(private|public)[\t\n\v\f\r ]*(,|})";
      llvm::Regex R(Match);
      SmallVector<StringRef, 2> Matches;

      if (R.match(Str, &Matches)) {
        MatchedStr = Matches[1];
        I += Matches[0].size();

        // Set the privacy flag if the privacy annotation in the
        // comma-delimited segment is at least as strict as the privacy
        // annotations in previous comma-delimited segments.
        if (MatchedStr.equals("private"))
          PrivacyFlags = clang::analyze_os_log::OSLogBufferItem::IsPrivate;
        else if (PrivacyFlags == 0 && MatchedStr.equals("public"))
          PrivacyFlags = clang::analyze_os_log::OSLogBufferItem::IsPublic;
      } else {
        size_t CommaOrBracePos =
            Str.find_if([](char c) { return c == ',' || c == '}'; });

        if (CommaOrBracePos == StringRef::npos) {
          // Neither a comma nor the closing brace was found.
          if (Warn)
            H.HandleIncompleteSpecifier(Start, E - Start);
          return true;
        }

        I += CommaOrBracePos + 1;
      }
      // Continue until the closing brace is found.
    } while (*(I - 1) == ',');

    // Set the privacy flag.
    switch (PrivacyFlags) {
    case 0:
      break;
    case clang::analyze_os_log::OSLogBufferItem::IsPrivate:
      FS.setIsPrivate(MatchedStr.data());
      break;
    case clang::analyze_os_log::OSLogBufferItem::IsPublic:
      FS.setIsPublic(MatchedStr.data());
      break;
    default:
      llvm_unreachable("Unexpected privacy flag value");
    }
  }

  // Look for flags (if any).
  bool hasMore = true;
  for ( ; I != E; ++I) {
    switch (*I) {
      default: hasMore = false; break;
      case '\'':
        // FIXME: POSIX specific.  Always accept?
        FS.setHasThousandsGrouping(I);
        break;
      case '-': FS.setIsLeftJustified(I); break;
      case '+': FS.setHasPlusPrefix(I); break;
      case ' ': FS.setHasSpacePrefix(I); break;
      case '#': FS.setHasAlternativeForm(I); break;
      case '0': FS.setHasLeadingZeros(I); break;
    }
    if (!hasMore)
      break;
  }

  if (I == E) {
    // No more characters left?
    if (Warn)
      H.HandleIncompleteSpecifier(Start, E - Start);
    return true;
  }

  // Look for the field width (if any).
  if (ParseFieldWidth(H, FS, Start, I, E,
                      FS.usesPositionalArg() ? nullptr : &argIndex))
    return true;

  if (I == E) {
    // No more characters left?
    if (Warn)
      H.HandleIncompleteSpecifier(Start, E - Start);
    return true;
  }

  // Look for the precision (if any).
  if (*I == '.') {
    ++I;
    if (I == E) {
      if (Warn)
        H.HandleIncompleteSpecifier(Start, E - Start);
      return true;
    }

    if (ParsePrecision(H, FS, Start, I, E,
                       FS.usesPositionalArg() ? nullptr : &argIndex))
      return true;

    if (I == E) {
      // No more characters left?
      if (Warn)
        H.HandleIncompleteSpecifier(Start, E - Start);
      return true;
    }
  }

  // Look for the length modifier.
  if (ParseLengthModifier(FS, I, E, LO) && I == E) {
    // No more characters left?
    if (Warn)
      H.HandleIncompleteSpecifier(Start, E - Start);
    return true;
  }

  // Look for the Objective-C modifier flags, if any.
  // We parse these here, even if they don't apply to
  // the conversion specifier, and then emit an error
  // later if the conversion specifier isn't '@'.  This
  // enables better recovery, and we don't know if
  // these flags are applicable until later.
  const char *ObjCModifierFlagsStart = nullptr,
             *ObjCModifierFlagsEnd = nullptr;
  if (*I == '[') {
    ObjCModifierFlagsStart = I;
    ++I;
    auto flagStart = I;
    for (;; ++I) {
      ObjCModifierFlagsEnd = I;
      if (I == E) {
        if (Warn)
          H.HandleIncompleteSpecifier(Start, E - Start);
        return true;
      }
      // Did we find the closing ']'?
      if (*I == ']') {
        if (ParseObjCFlags(H, FS, flagStart, I, Warn))
          return true;
        ++I;
        break;
      }
      // There are no separators defined yet for multiple
      // Objective-C modifier flags.  When those are
      // defined, this is the place to check.
    }
  }

  if (*I == '\0') {
    // Detect spurious null characters, which are likely errors.
    H.HandleNullChar(I);
    return true;
  }

  // Finally, look for the conversion specifier.
  const char *conversionPosition = I++;
  ConversionSpecifier::Kind k = ConversionSpecifier::InvalidSpecifier;
  switch (*conversionPosition) {
    default:
      break;
    // C99: 7.19.6.1 (section 8).
    case '%': k = ConversionSpecifier::PercentArg;   break;
    case 'A': k = ConversionSpecifier::AArg; break;
    case 'E': k = ConversionSpecifier::EArg; break;
    case 'F': k = ConversionSpecifier::FArg; break;
    case 'G': k = ConversionSpecifier::GArg; break;
    case 'X': k = ConversionSpecifier::XArg; break;
    case 'a': k = ConversionSpecifier::aArg; break;
    case 'c': k = ConversionSpecifier::cArg; break;
    case 'd': k = ConversionSpecifier::dArg; break;
    case 'e': k = ConversionSpecifier::eArg; break;
    case 'f': k = ConversionSpecifier::fArg; break;
    case 'g': k = ConversionSpecifier::gArg; break;
    case 'i': k = ConversionSpecifier::iArg; break;
    case 'n': k = ConversionSpecifier::nArg; break;
    case 'o': k = ConversionSpecifier::oArg; break;
    case 'p': k = ConversionSpecifier::pArg; break;
    case 's': k = ConversionSpecifier::sArg; break;
    case 'u': k = ConversionSpecifier::uArg; break;
    case 'x': k = ConversionSpecifier::xArg; break;
    // POSIX specific.
    case 'C': k = ConversionSpecifier::CArg; break;
    case 'S': k = ConversionSpecifier::SArg; break;
    // Apple extension for os_log
    case 'P':
      k = ConversionSpecifier::PArg;
      break;
    // Objective-C.
    case '@': k = ConversionSpecifier::ObjCObjArg; break;
    // Glibc specific.
    case 'm': k = ConversionSpecifier::PrintErrno; break;
    // FreeBSD kernel specific.
    case 'b':
      if (isFreeBSDKPrintf)
        k = ConversionSpecifier::FreeBSDbArg; // int followed by char *
      break;
    case 'r':
      if (isFreeBSDKPrintf)
        k = ConversionSpecifier::FreeBSDrArg; // int
      break;
    case 'y':
      if (isFreeBSDKPrintf)
        k = ConversionSpecifier::FreeBSDyArg; // int
      break;
    // Apple-specific.
    case 'D':
      if (isFreeBSDKPrintf)
        k = ConversionSpecifier::FreeBSDDArg; // void * followed by char *
      else if (Target.getTriple().isOSDarwin())
        k = ConversionSpecifier::DArg;
      break;
    case 'O':
      if (Target.getTriple().isOSDarwin())
        k = ConversionSpecifier::OArg;
      break;
    case 'U':
      if (Target.getTriple().isOSDarwin())
        k = ConversionSpecifier::UArg;
      break;
    // MS specific.
    case 'Z':
      if (Target.getTriple().isOSMSVCRT())
        k = ConversionSpecifier::ZArg;
  }
  
  // Check to see if we used the Objective-C modifier flags with
  // a conversion specifier other than '@'.
  if (k != ConversionSpecifier::ObjCObjArg &&
      k != ConversionSpecifier::InvalidSpecifier &&
      ObjCModifierFlagsStart) {
    H.HandleObjCFlagsWithNonObjCConversion(ObjCModifierFlagsStart,
                                           ObjCModifierFlagsEnd + 1,
                                           conversionPosition);
    return true;
  }

  PrintfConversionSpecifier CS(conversionPosition, k);
  FS.setConversionSpecifier(CS);
  if (CS.consumesDataArgument() && !FS.usesPositionalArg())
    FS.setArgIndex(argIndex++);
  // FreeBSD kernel specific.
  if (k == ConversionSpecifier::FreeBSDbArg ||
      k == ConversionSpecifier::FreeBSDDArg)
    argIndex++;

  if (k == ConversionSpecifier::InvalidSpecifier) {
    unsigned Len = I - Start;
    if (ParseUTF8InvalidSpecifier(Start, E, Len)) {
      CS.setEndScanList(Start + Len);
      FS.setConversionSpecifier(CS);
    }
    // Assume the conversion takes one argument.
    return !H.HandleInvalidPrintfConversionSpecifier(FS, Start, Len);
  }
  return PrintfSpecifierResult(Start, FS);
}
Example #11
0
/// GetDwarfFile - takes a file name an number to place in the dwarf file and
/// directory tables.  If the file number has already been allocated it is an
/// error and zero is returned and the client reports the error, else the
/// allocated file number is returned.  The file numbers may be in any order.
unsigned MCContext::GetDwarfFile(StringRef Directory, StringRef FileName,
                                 unsigned FileNumber, unsigned CUID) {
  // TODO: a FileNumber of zero says to use the next available file number.
  // Note: in GenericAsmParser::ParseDirectiveFile() FileNumber was checked
  // to not be less than one.  This needs to be change to be not less than zero.

  SmallVectorImpl<MCDwarfFile *>& MCDwarfFiles = MCDwarfFilesCUMap[CUID];
  SmallVectorImpl<StringRef>& MCDwarfDirs = MCDwarfDirsCUMap[CUID];
  // Make space for this FileNumber in the MCDwarfFiles vector if needed.
  if (FileNumber >= MCDwarfFiles.size()) {
    MCDwarfFiles.resize(FileNumber + 1);
  } else {
    MCDwarfFile *&ExistingFile = MCDwarfFiles[FileNumber];
    if (ExistingFile)
      // It is an error to use see the same number more than once.
      return 0;
  }

  // Get the new MCDwarfFile slot for this FileNumber.
  MCDwarfFile *&File = MCDwarfFiles[FileNumber];

  if (Directory.empty()) {
    // Separate the directory part from the basename of the FileName.
    StringRef tFileName = sys::path::filename(FileName);
    if (!tFileName.empty()) {
      Directory = sys::path::parent_path(FileName);
      if (!Directory.empty())
        FileName = tFileName;
    }
  }

  // Find or make a entry in the MCDwarfDirs vector for this Directory.
  // Capture directory name.
  unsigned DirIndex;
  if (Directory.empty()) {
    // For FileNames with no directories a DirIndex of 0 is used.
    DirIndex = 0;
  } else {
    DirIndex = 0;
    for (unsigned End = MCDwarfDirs.size(); DirIndex < End; DirIndex++) {
      if (Directory == MCDwarfDirs[DirIndex])
        break;
    }
    if (DirIndex >= MCDwarfDirs.size()) {
      char *Buf = static_cast<char *>(Allocate(Directory.size()));
      memcpy(Buf, Directory.data(), Directory.size());
      MCDwarfDirs.push_back(StringRef(Buf, Directory.size()));
    }
    // The DirIndex is one based, as DirIndex of 0 is used for FileNames with
    // no directories.  MCDwarfDirs[] is unlike MCDwarfFiles[] in that the
    // directory names are stored at MCDwarfDirs[DirIndex-1] where FileNames
    // are stored at MCDwarfFiles[FileNumber].Name .
    DirIndex++;
  }

  // Now make the MCDwarfFile entry and place it in the slot in the MCDwarfFiles
  // vector.
  char *Buf = static_cast<char *>(Allocate(FileName.size()));
  memcpy(Buf, FileName.data(), FileName.size());
  File = new (*this) MCDwarfFile(StringRef(Buf, FileName.size()), DirIndex);

  // return the allocated FileNumber.
  return FileNumber;
}
Example #12
0
extern "C" const char* LLVMRustGetHostCPUName(size_t *len) {
  StringRef Name = sys::getHostCPUName();
  *len = Name.size();
  return Name.data();
}
Example #13
0
StringRef StringScratchSpace::copyString(StringRef string) {
  void *memory = Allocator.Allocate(string.size(), alignof(char));
  memcpy(memory, string.data(), string.size());
  return StringRef(static_cast<char *>(memory), string.size());
}
Example #14
0
bool swift::omitNeedlessWords(StringRef &baseName,
                              MutableArrayRef<StringRef> argNames,
                              StringRef firstParamName,
                              OmissionTypeName resultType,
                              OmissionTypeName contextType,
                              ArrayRef<OmissionTypeName> paramTypes,
                              bool returnsSelf,
                              bool isProperty,
                              const InheritedNameSet *allPropertyNames,
                              StringScratchSpace &scratch) {
  bool anyChanges = false;

  /// Local function that lowercases all of the base names and
  /// argument names before returning.
  auto lowercaseAcronymsForReturn = [&] {
    StringRef newBaseName = toLowercaseInitialisms(baseName, scratch);
    if (baseName.data() != newBaseName.data()) {
      baseName = newBaseName;
      anyChanges = true;
    }

    for (StringRef &argName : argNames) {
      StringRef newArgName = toLowercaseInitialisms(argName, scratch);
      if (argName.data() != newArgName.data()) {
        argName = newArgName;
        anyChanges = true;
      }
    }

    return anyChanges;
  };

  // If the result type matches the context, remove the context type from the
  // prefix of the name.
  bool resultTypeMatchesContext = returnsSelf || (resultType == contextType);
  if (resultTypeMatchesContext) {
    StringRef newBaseName = omitNeedlessWordsFromPrefix(baseName, contextType,
                                                        scratch);
    if (newBaseName != baseName) {
      baseName = newBaseName;
      anyChanges = true;
    }
  }

  // Strip the context type from the base name of a method.
  if (!isProperty) {
    StringRef newBaseName = ::omitNeedlessWords(baseName, contextType,
                                                NameRole::BaseNameSelf,
                                                allPropertyNames, scratch);
    if (newBaseName != baseName) {
      baseName = newBaseName;
      anyChanges = true;
    }
  }

  if (paramTypes.empty()) {
    if (resultTypeMatchesContext) {
      StringRef newBaseName = ::omitNeedlessWords(
                                baseName,
                                returnsSelf ? contextType : resultType,
                                NameRole::Property,
                                allPropertyNames,
                                scratch);
      if (newBaseName != baseName) {
        baseName = newBaseName;
        anyChanges = true;
      }
    }

    return lowercaseAcronymsForReturn();
  }

  if (camel_case::getFirstWord(baseName) == "set") {
    StringRef newBaseName = ::omitNeedlessWords(
                              baseName,
                              contextType,
                              NameRole::Property,
                              allPropertyNames,
                              scratch);
    if (newBaseName != baseName) {
      baseName = newBaseName;
      anyChanges = true;
    }
  }

  // If needed, split the base name.
  if (!argNames.empty() &&
      splitBaseName(baseName, argNames[0], paramTypes[0], firstParamName))
    anyChanges = true;

  // Omit needless words based on parameter types.
  for (unsigned i = 0, n = argNames.size(); i != n; ++i) {
    // If there is no corresponding parameter, there is nothing to
    // omit.
    if (i >= paramTypes.size()) continue;

    // Omit needless words based on the type of the parameter.
    NameRole role = i > 0 ? NameRole::SubsequentParameter
      : argNames[0].empty() ? NameRole::BaseName
      : baseName == "init" ? NameRole::SubsequentParameter
      : paramTypes[0].hasDefaultArgument() ? NameRole::SubsequentParameter
      : NameRole::FirstParameter;

    // Omit needless words from the name.
    StringRef name = role == NameRole::BaseName ? baseName : argNames[i];
    StringRef newName = ::omitNeedlessWords(name, paramTypes[i], role,
                                            role == NameRole::BaseName 
                                              ? allPropertyNames
                                              : nullptr,
                                            scratch);

    if (name == newName) continue;

    // Record this change.
    anyChanges = true;
    if (role == NameRole::BaseName) {
      baseName = newName;
    } else {
      argNames[i] = newName;
    }
  }

  return lowercaseAcronymsForReturn();
}
Example #15
0
unsigned RuntimeDyldImpl::emitSection(ObjectImage &Obj,
                                      const SectionRef &Section, bool IsCode) {

  StringRef data;
  uint64_t Alignment64;
  Check(Section.getContents(data));
  Check(Section.getAlignment(Alignment64));

  unsigned Alignment = (unsigned)Alignment64 & 0xffffffffL;
  bool IsRequired;
  bool IsVirtual;
  bool IsZeroInit;
  bool IsReadOnly;
  uint64_t DataSize;
  unsigned PaddingSize = 0;
  unsigned StubBufSize = 0;
  StringRef Name;
  Check(Section.isRequiredForExecution(IsRequired));
  Check(Section.isVirtual(IsVirtual));
  Check(Section.isZeroInit(IsZeroInit));
  Check(Section.isReadOnlyData(IsReadOnly));
  Check(Section.getSize(DataSize));
  Check(Section.getName(Name));

  StubBufSize = computeSectionStubBufSize(Obj, Section);

  // The .eh_frame section (at least on Linux) needs an extra four bytes padded
  // with zeroes added at the end.  For MachO objects, this section has a
  // slightly different name, so this won't have any effect for MachO objects.
  if (Name == ".eh_frame")
    PaddingSize = 4;

  uintptr_t Allocate;
  unsigned SectionID = Sections.size();
  uint8_t *Addr;
  const char *pData = 0;

  // Some sections, such as debug info, don't need to be loaded for execution.
  // Leave those where they are.
  if (IsRequired) {
    Allocate = DataSize + PaddingSize + StubBufSize;
    Addr = IsCode ? MemMgr->allocateCodeSection(Allocate, Alignment, SectionID,
                                                Name)
                  : MemMgr->allocateDataSection(Allocate, Alignment, SectionID,
                                                Name, IsReadOnly);
    if (!Addr)
      report_fatal_error("Unable to allocate section memory!");

    // Virtual sections have no data in the object image, so leave pData = 0
    if (!IsVirtual)
      pData = data.data();

    // Zero-initialize or copy the data from the image
    if (IsZeroInit || IsVirtual)
      memset(Addr, 0, DataSize);
    else
      memcpy(Addr, pData, DataSize);

    // Fill in any extra bytes we allocated for padding
    if (PaddingSize != 0) {
      memset(Addr + DataSize, 0, PaddingSize);
      // Update the DataSize variable so that the stub offset is set correctly.
      DataSize += PaddingSize;
    }

    DEBUG(dbgs() << "emitSection SectionID: " << SectionID << " Name: " << Name
                 << " obj addr: " << format("%p", pData)
                 << " new addr: " << format("%p", Addr)
                 << " DataSize: " << DataSize << " StubBufSize: " << StubBufSize
                 << " Allocate: " << Allocate << "\n");
    Obj.updateSectionAddress(Section, (uint64_t)Addr);
  } else {
    // Even if we didn't load the section, we need to record an entry for it
    // to handle later processing (and by 'handle' I mean don't do anything
    // with these sections).
    Allocate = 0;
    Addr = 0;
    DEBUG(dbgs() << "emitSection SectionID: " << SectionID << " Name: " << Name
                 << " obj addr: " << format("%p", data.data()) << " new addr: 0"
                 << " DataSize: " << DataSize << " StubBufSize: " << StubBufSize
                 << " Allocate: " << Allocate << "\n");
  }

  Sections.push_back(SectionEntry(Name, Addr, DataSize, (uintptr_t)pData));
  return SectionID;
}
void ClangCommentPrinter::printCommentsUntil(ClangNode Node) {
  const auto &Ctx = ClangLoader.getClangASTContext();
  const auto &SM = Ctx.getSourceManager();

  clang::SourceLocation NodeLoc =
      SM.getFileLoc(Node.getSourceRange().getBegin());
  if (NodeLoc.isInvalid())
    return;
  unsigned NodeLineNo = SM.getSpellingLineNumber(NodeLoc);
  clang::FileID FID = SM.getFileID(NodeLoc);
  if (FID.isInvalid())
    return;
  clang::SourceLocation FileLoc = SM.getLocForStartOfFile(FID);
  StringRef Text = SM.getBufferData(FID);
  if (Text.empty())
    return;

  const char *BufStart = Text.data();
  const char *BufPtr = BufStart + getResumeOffset(FID);
  const char *BufEnd = BufStart + Text.size();
  assert(BufPtr <= BufEnd);
  if (BufPtr == BufEnd)
    return; // nothing left.

  clang::Lexer Lex(FileLoc, Ctx.getLangOpts(), BufStart, BufPtr, BufEnd);
  Lex.SetCommentRetentionState(true);

  unsigned &LastPrintedLineNo = LastEntityLines[FID];
  clang::Token Tok;
  do {
    BufPtr = Lex.getBufferLocation();
    Lex.LexFromRawLexer(Tok);
    if (Tok.is(clang::tok::eof))
      break;
    if (Tok.isNot(clang::tok::comment))
      continue;

    // Reached a comment.

    clang::SourceLocation CommentLoc = Tok.getLocation();
    std::pair<clang::FileID, unsigned> LocInfo =
      SM.getDecomposedLoc(CommentLoc);
    assert(LocInfo.first == FID);

    unsigned LineNo = SM.getLineNumber(LocInfo.first, LocInfo.second);
    if (LineNo > NodeLineNo)
      break; // Comment is past the clang node.

    bool IsDocComment = isDocumentationComment(CommentLoc, Node);

    // Print out the comment.

    StringRef CommentText(BufStart + LocInfo.second, Tok.getLength());

    // Check if comment is on same line but after the declaration.
    if (SM.isBeforeInTranslationUnit(NodeLoc, Tok.getLocation())) {
      if (!IsDocComment)
        PendingComments.push_back(CommentText);
      continue;
    }

    if (LastPrintedLineNo && LineNo - LastPrintedLineNo > 1) {
      *this << "\n";
      printIndent();
    }
    if (!IsDocComment) {
      unsigned StartLocCol = SM.getSpellingColumnNumber(Tok.getLocation());
      printComment(CommentText, StartLocCol);
    }
    LastPrintedLineNo =
        SM.getLineNumber(LocInfo.first, LocInfo.second + Tok.getLength());

  } while (true);

  // Resume printing comments from this point.
  setResumeOffset(FID, BufPtr - BufStart);
}
Example #17
0
ObjectImage *RuntimeDyldImpl::loadObject(ObjectImage *InputObject) {
  MutexGuard locked(lock);

  std::unique_ptr<ObjectImage> Obj(InputObject);
  if (!Obj)
    return NULL;

  // Save information about our target
  Arch = (Triple::ArchType)Obj->getArch();
  IsTargetLittleEndian = Obj->getObjectFile()->isLittleEndian();

  // Compute the memory size required to load all sections to be loaded
  // and pass this information to the memory manager
  if (MemMgr->needsToReserveAllocationSpace()) {
    uint64_t CodeSize = 0, DataSizeRO = 0, DataSizeRW = 0;
    computeTotalAllocSize(*Obj, CodeSize, DataSizeRO, DataSizeRW);
    MemMgr->reserveAllocationSpace(CodeSize, DataSizeRO, DataSizeRW);
  }

  // Symbols found in this object
  StringMap<SymbolLoc> LocalSymbols;
  // Used sections from the object file
  ObjSectionToIDMap LocalSections;

  // Common symbols requiring allocation, with their sizes and alignments
  CommonSymbolMap CommonSymbols;
  // Maximum required total memory to allocate all common symbols
  uint64_t CommonSize = 0;

  // Parse symbols
  DEBUG(dbgs() << "Parse symbols:\n");
  for (symbol_iterator I = Obj->begin_symbols(), E = Obj->end_symbols(); I != E;
       ++I) {
    object::SymbolRef::Type SymType;
    StringRef Name;
    Check(I->getType(SymType));
    Check(I->getName(Name));

    uint32_t Flags = I->getFlags();

    bool IsCommon = Flags & SymbolRef::SF_Common;
    if (IsCommon) {
      // Add the common symbols to a list.  We'll allocate them all below.
      uint32_t Align;
      Check(I->getAlignment(Align));
      uint64_t Size = 0;
      Check(I->getSize(Size));
      CommonSize += Size + Align;
      CommonSymbols[*I] = CommonSymbolInfo(Size, Align);
    } else {
      if (SymType == object::SymbolRef::ST_Function ||
          SymType == object::SymbolRef::ST_Data ||
          SymType == object::SymbolRef::ST_Unknown) {
        uint64_t FileOffset;
        StringRef SectionData;
        bool IsCode;
        section_iterator SI = Obj->end_sections();
        Check(I->getFileOffset(FileOffset));
        Check(I->getSection(SI));
        if (SI == Obj->end_sections())
          continue;
        Check(SI->getContents(SectionData));
        Check(SI->isText(IsCode));
        const uint8_t *SymPtr =
            (const uint8_t *)Obj->getData().data() + (uintptr_t)FileOffset;
        uintptr_t SectOffset =
            (uintptr_t)(SymPtr - (const uint8_t *)SectionData.begin());
        unsigned SectionID =
            findOrEmitSection(*Obj, *SI, IsCode, LocalSections);
        LocalSymbols[Name.data()] = SymbolLoc(SectionID, SectOffset);
        DEBUG(dbgs() << "\tFileOffset: " << format("%p", (uintptr_t)FileOffset)
                     << " flags: " << Flags << " SID: " << SectionID
                     << " Offset: " << format("%p", SectOffset));
        GlobalSymbolTable[Name] = SymbolLoc(SectionID, SectOffset);
      }
    }
    DEBUG(dbgs() << "\tType: " << SymType << " Name: " << Name << "\n");
  }

  // Allocate common symbols
  if (CommonSize != 0)
    emitCommonSymbols(*Obj, CommonSymbols, CommonSize, LocalSymbols);

  // Parse and process relocations
  DEBUG(dbgs() << "Parse relocations:\n");
  for (section_iterator SI = Obj->begin_sections(), SE = Obj->end_sections();
       SI != SE; ++SI) {
    unsigned SectionID = 0;
    StubMap Stubs;
    section_iterator RelocatedSection = SI->getRelocatedSection();

    if (SI->relocation_empty() && !ProcessAllSections)
      continue;

    bool IsCode = false;
    Check(RelocatedSection->isText(IsCode));
    SectionID =
        findOrEmitSection(*Obj, *RelocatedSection, IsCode, LocalSections);
    DEBUG(dbgs() << "\tSectionID: " << SectionID << "\n");

    for (relocation_iterator I = SI->relocation_begin(),
         E = SI->relocation_end(); I != E;)
      I = processRelocationRef(SectionID, I, *Obj, LocalSections, LocalSymbols,
                               Stubs);
  }

  // Give the subclasses a chance to tie-up any loose ends.
  finalizeLoad(LocalSections);

  return Obj.release();
}
Example #18
0
SourceCompleteResult
ide::isSourceInputComplete(std::unique_ptr<llvm::MemoryBuffer> MemBuf,
                           SourceFileKind SFKind) {
  SourceManager SM;
  auto BufferID = SM.addNewSourceBuffer(std::move(MemBuf));
  ParserUnit Parse(SM, SFKind, BufferID);
  Parser &P = Parse.getParser();

  bool Done;
  do {
    P.parseTopLevel();
    Done = P.Tok.is(tok::eof);
  } while (!Done);

  SourceCompleteResult SCR;
  SCR.IsComplete = !P.isInputIncomplete();

  // Use the same code that was in the REPL code to track the indent level
  // for now. In the future we should get this from the Parser if possible.

  CharSourceRange entireRange = SM.getRangeForBuffer(BufferID);
  StringRef Buffer = SM.extractText(entireRange);
  const char *SourceStart = Buffer.data();
  const char *SourceEnd = Buffer.data() + Buffer.size();
  const char *LineStart = SourceStart;
  const char *LineSourceStart = nullptr;
  uint32_t LineIndent = 0;
  struct IndentInfo {
    StringRef Prefix;
    uint32_t Indent;
    IndentInfo(const char *s, size_t n, uint32_t i) :
      Prefix(s, n),
      Indent(i) {}
  };
  SmallVector<IndentInfo, 4> IndentInfos;
  for (const char *p = SourceStart; p<SourceEnd; ++p) {
    switch (*p) {
    case '\r':
    case '\n':
      LineIndent = 0;
      LineSourceStart = nullptr;
      LineStart = p + 1;
      break;

    case '"':
      p = skipStringInCode (p, SourceEnd);
      break;

    case '{':
    case '(':
    case '[':
      ++LineIndent;
      if (LineSourceStart == nullptr)
        IndentInfos.push_back(IndentInfo(LineStart,
                                         p - LineStart,
                                         LineIndent));
      else
        IndentInfos.push_back(IndentInfo(LineStart,
                                         LineSourceStart - LineStart,
                                         LineIndent));
      break;

    case '}':
    case ')':
    case ']':
      if (LineIndent > 0)
        --LineIndent;
      if (!IndentInfos.empty())
        IndentInfos.pop_back();
      break;

    default:
      if (LineSourceStart == nullptr && !isspace(*p))
        LineSourceStart = p;
      break;
    }
    if (*p == '\0')
      break;
  }
  if (!IndentInfos.empty()) {
    SCR.IndentPrefix = IndentInfos.back().Prefix.str();
    // Trim off anything that follows a non-space character
    const size_t pos = SCR.IndentPrefix.find_first_not_of(" \t");
    if (pos != std::string::npos)
        SCR.IndentPrefix.erase(pos);
    SCR.IndentLevel = IndentInfos.back().Indent;
  }
  return SCR;
}
Example #19
0
    virtual void NotifyObjectEmitted(const ObjectImage &obj)
#endif
    {
        uint64_t Addr;
        uint64_t Size;
        object::SymbolRef::Type SymbolType;
#ifdef LLVM36
        object::section_iterator Section = obj.section_begin();
        object::section_iterator EndSection = obj.section_end();
        uint64_t SectionAddr = 0;
        StringRef sName;
#else
        object::section_iterator Section = obj.begin_sections();
        object::section_iterator EndSection = obj.end_sections();
        bool isText;
#ifndef _OS_LINUX_
        StringRef sName;
#endif
#endif

#ifndef LLVM36
        uint64_t SectionAddr = 0;
#endif
        uint64_t SectionSize = 0;

#if defined(_OS_WINDOWS_)
        uint64_t SectionAddrCheck = 0; // assert that all of the Sections are at the same location
#if defined(_CPU_X86_64_)
        uint8_t *UnwindData = NULL;
        uint8_t *catchjmp = NULL;
        for (const object::SymbolRef &sym_iter : obj.symbols()) {
#  ifdef LLVM37
            sName = sym_iter.getName().get();
#  else
            sym_iter.getName(sName);
#  endif
            if (sName.equals("__UnwindData")) {
#  ifdef LLVM37
                Addr = sym_iter.getAddress().get();
#  else
                sym_iter.getAddress(Addr);
#  endif
                sym_iter.getSection(Section);
#  ifdef LLVM36
                assert(Section->isText());
#    ifdef LLVM38
                SectionAddr = L.getSectionLoadAddress(*Section);
#    else
                Section->getName(sName);
                SectionAddr = L.getSectionLoadAddress(sName);
#    endif
                Addr += SectionAddr;
#  else
                if (Section->isText(isText) || !isText) assert(0 && "!isText");
                Section->getAddress(SectionAddr);
#  endif
                UnwindData = (uint8_t*)Addr;
                if (SectionAddrCheck)
                    assert(SectionAddrCheck == SectionAddr);
                else
                    SectionAddrCheck = SectionAddr;
            }
            if (sName.equals("__catchjmp")) {
#  ifdef LLVM37
                Addr = sym_iter.getAddress().get();
#  else
                sym_iter.getAddress(Addr);
#  endif
                sym_iter.getSection(Section);
#  ifdef LLVM36
                assert(Section->isText());
#    ifdef LLVM38
                SectionAddr = L.getSectionLoadAddress(*Section);
#    else
                Section->getName(sName);
                SectionAddr = L.getSectionLoadAddress(sName);
#    endif
                Addr += SectionAddr;
#  else
                if (Section->isText(isText) || !isText) assert(0 && "!isText");
                Section->getAddress(SectionAddr);
#  endif
                catchjmp = (uint8_t*)Addr;
                if (SectionAddrCheck)
                    assert(SectionAddrCheck == SectionAddr);
                else
                    SectionAddrCheck = SectionAddr;
            }
        }
        assert(catchjmp);
        assert(UnwindData);
        catchjmp[0] = 0x48;
        catchjmp[1] = 0xb8; // mov RAX, QWORD PTR [&_seh_exception_handle]
        *(uint64_t*)(&catchjmp[2]) = (uint64_t)&_seh_exception_handler;
        catchjmp[10] = 0xff;
        catchjmp[11] = 0xe0; // jmp RAX
        UnwindData[0] = 0x09; // version info, UNW_FLAG_EHANDLER
        UnwindData[1] = 4;    // size of prolog (bytes)
        UnwindData[2] = 2;    // count of unwind codes (slots)
        UnwindData[3] = 0x05; // frame register (rbp) = rsp
        UnwindData[4] = 4;    // second instruction
        UnwindData[5] = 0x03; // mov RBP, RSP
        UnwindData[6] = 1;    // first instruction
        UnwindData[7] = 0x50; // push RBP
        *(DWORD*)&UnwindData[8] = (DWORD)(catchjmp - (uint8_t*)SectionAddr); // relative location of catchjmp
#else // defined(_OS_X86_64_)
        uint8_t *UnwindData = NULL;
#endif // defined(_OS_X86_64_)
#endif // defined(_OS_WINDOWS_)

#ifdef LLVM35
        for (const object::SymbolRef &sym_iter : obj.symbols()) {
#           ifdef LLVM37
                SymbolType = sym_iter.getType();
#           else
                sym_iter.getType(SymbolType);
#           endif
            if (SymbolType != object::SymbolRef::ST_Function) continue;
#           ifdef LLVM37
                Addr = sym_iter.getAddress().get();
#           else
                sym_iter.getAddress(Addr);
#           endif
#           ifdef LLVM38
                Section = sym_iter.getSection().get();
#           else
                sym_iter.getSection(Section);
#           endif
            if (Section == EndSection) continue;
#if defined(LLVM36)
            if (!Section->isText()) continue;
#    ifdef LLVM38
            SectionAddr = L.getSectionLoadAddress(*Section);
#    else
            Section->getName(sName);
            SectionAddr = L.getSectionLoadAddress(sName);
#    endif
            Addr += SectionAddr;
#else
            if (Section->isText(isText) || !isText) continue;
#endif
#if defined(LLVM36)
            SectionSize = Section->getSize();
#else
            Section->getAddress(SectionAddr);
            Section->getSize(SectionSize);
#endif
#ifdef _OS_DARWIN_
#   if defined(LLVM37)
            Size = Section->getSize();
            sName = sym_iter.getName().get();
#   else
            sym_iter.getName(sName);
#   endif
#   if defined(LLVM36)
            if (sName[0] == '_') {
                sName = sName.substr(1);
            }
#   else
            Addr = ((MCJIT*)jl_ExecutionEngine)->getSymbolAddress(sName, true);
            if (!Addr && sName[0] == '_') {
                sName = sName.substr(1);
                Addr = ((MCJIT*)jl_ExecutionEngine)->getSymbolAddress(sName, true);
            }
            if (!Addr) continue;
#   endif
#elif defined(_OS_WINDOWS_)
#   if defined(LLVM37)
            assert(obj.isELF());
            Size = ((llvm::object::ELFSymbolRef)sym_iter).getSize();
            sName = sym_iter.getName().get();
#   else
            sym_iter.getSize(Size);
            sym_iter.getName(sName);
#   endif
#   ifdef _CPU_X86_
            if (sName[0] == '_') sName = sName.substr(1);
#   endif
            if (SectionAddrCheck)
                assert(SectionAddrCheck == SectionAddr);
            else
                SectionAddrCheck = SectionAddr;
            create_PRUNTIME_FUNCTION(
                   (uint8_t*)(intptr_t)Addr, (size_t)Size, sName,
                   (uint8_t*)(intptr_t)SectionAddr, (size_t)SectionSize, UnwindData);
#endif
            const object::ObjectFile *objfile =
#ifdef LLVM36
                &obj;
#else
                obj.getObjectFile();
#endif
            ObjectInfo tmp = {objfile, SectionSize
#ifdef LLVM37
                ,L.clone().release()
#elif defined(LLVM36)
                ,(size_t)SectionAddr
#endif
#ifdef _OS_DARWIN_
                ,strndup(sName.data(), sName.size())
#endif
            };
            objectmap[Addr] = tmp;
        }
#else //LLVM34
        error_code itererr;
        object::symbol_iterator sym_iter = obj.begin_symbols();
        object::symbol_iterator sym_end = obj.end_symbols();
        for (; sym_iter != sym_end; sym_iter.increment(itererr)) {
            sym_iter->getType(SymbolType);
            if (SymbolType != object::SymbolRef::ST_Function) continue;
            sym_iter->getAddress(Addr);
            sym_iter->getSize(Size);

            ObjectInfo tmp = {obj.getObjectFile(), (size_t)Size};
            objectmap[Addr] = tmp;
        }
#endif
    }
/// CopyStringRef - Copies contents of a StringRef into a block of memory and
/// null-terminates it.
static void CopyStringRef(char *Memory, StringRef Data) {
  memcpy(Memory, Data.data(), Data.size());
  Memory[Data.size()] = 0; // Null terminate string.
}
Example #21
0
    virtual void NotifyObjectEmitted(const ObjectImage &obj)
#endif
    {
        int8_t gc_state = jl_gc_safe_enter();
        uv_rwlock_wrlock(&threadsafe);
        jl_gc_safe_leave(gc_state);
#ifdef LLVM36
        object::section_iterator Section = obj.section_begin();
        object::section_iterator EndSection = obj.section_end();
#else
        object::section_iterator Section = obj.begin_sections();
        object::section_iterator EndSection = obj.end_sections();
#endif

#if defined(_OS_WINDOWS_)
        uint64_t SectionAddrCheck = 0; // assert that all of the Sections are at the same location
        uint8_t *UnwindData = NULL;
#if defined(_CPU_X86_64_)
        uint8_t *catchjmp = NULL;
        for (const object::SymbolRef &sym_iter : obj.symbols()) {
            StringRef sName;
#ifdef LLVM37
            sName = sym_iter.getName().get();
#else
            sym_iter.getName(sName);
#endif
            uint8_t **pAddr = NULL;
            if (sName.equals("__UnwindData")) {
                pAddr = &UnwindData;
            }
            else if (sName.equals("__catchjmp")) {
                pAddr = &catchjmp;
            }
            if (pAddr) {
                uint64_t Addr, SectionAddr;
#if defined(LLVM38)
                Addr = sym_iter.getAddress().get();
                Section = sym_iter.getSection().get();
                assert(Section != EndSection && Section->isText());
                SectionAddr = L.getSectionLoadAddress(*Section);
#elif defined(LLVM37)
                Addr = sym_iter.getAddress().get();
                sym_iter.getSection(Section);
                assert(Section != EndSection && Section->isText());
                Section->getName(sName);
                SectionAddr = L.getSectionLoadAddress(sName);
#elif defined(LLVM36)
                sym_iter.getAddress(Addr);
                sym_iter.getSection(Section);
                assert(Section != EndSection && Section->isText());
                Section->getName(sName);
                SectionAddr = L.getSectionLoadAddress(sName);
#else // LLVM35
                sym_iter.getAddress(Addr);
                sym_iter.getSection(Section);
                assert(Section != EndSection);
                assert(!Section->isText(isText) && isText);
                Section->getAddress(SectionAddr);
#endif
#ifdef LLVM36
                Addr += SectionAddr;
#endif
                *pAddr = (uint8_t*)Addr;
                if (SectionAddrCheck)
                    assert(SectionAddrCheck == SectionAddr);
                else
                    SectionAddrCheck = SectionAddr;
            }
        }
        assert(catchjmp);
        assert(UnwindData);
        assert(SectionAddrCheck);
        catchjmp[0] = 0x48;
        catchjmp[1] = 0xb8; // mov RAX, QWORD PTR [&_seh_exception_handle]
        *(uint64_t*)(&catchjmp[2]) = (uint64_t)&_seh_exception_handler;
        catchjmp[10] = 0xff;
        catchjmp[11] = 0xe0; // jmp RAX
        UnwindData[0] = 0x09; // version info, UNW_FLAG_EHANDLER
        UnwindData[1] = 4;    // size of prolog (bytes)
        UnwindData[2] = 2;    // count of unwind codes (slots)
        UnwindData[3] = 0x05; // frame register (rbp) = rsp
        UnwindData[4] = 4;    // second instruction
        UnwindData[5] = 0x03; // mov RBP, RSP
        UnwindData[6] = 1;    // first instruction
        UnwindData[7] = 0x50; // push RBP
        *(DWORD*)&UnwindData[8] = (DWORD)(catchjmp - (uint8_t*)SectionAddrCheck); // relative location of catchjmp
#endif // defined(_OS_X86_64_)
#endif // defined(_OS_WINDOWS_)

#ifdef LLVM37
        auto symbols = object::computeSymbolSizes(obj);
        for(const auto &sym_size : symbols) {
            const object::SymbolRef &sym_iter = sym_size.first;
            object::SymbolRef::Type SymbolType = sym_iter.getType();
            if (SymbolType != object::SymbolRef::ST_Function) continue;
            uint64_t Size = sym_size.second;
            uint64_t Addr = sym_iter.getAddress().get();
#ifdef LLVM38
            Section = sym_iter.getSection().get();
#else
            sym_iter.getSection(Section);
#endif
            if (Section == EndSection) continue;
            if (!Section->isText()) continue;
#ifdef LLVM38
            uint64_t SectionAddr = L.getSectionLoadAddress(*Section);
#else
            StringRef secName;
            Section->getName(secName);
            uint64_t SectionAddr = L.getSectionLoadAddress(secName);
#endif
            Addr += SectionAddr;
            StringRef sName = sym_iter.getName().get();
#if defined(_OS_WINDOWS_)
            uint64_t SectionSize = Section->getSize();
            if (SectionAddrCheck)
                assert(SectionAddrCheck == SectionAddr);
            else
                SectionAddrCheck = SectionAddr;
            create_PRUNTIME_FUNCTION(
                   (uint8_t*)(intptr_t)Addr, (size_t)Size, sName,
                   (uint8_t*)(intptr_t)SectionAddr, (size_t)SectionSize, UnwindData);
#endif
            StringMap<jl_lambda_info_t*>::iterator linfo_it = linfo_in_flight.find(sName);
            jl_lambda_info_t *linfo = NULL;
            if (linfo_it != linfo_in_flight.end()) {
                linfo = linfo_it->second;
                linfo_in_flight.erase(linfo_it);
            }
            ObjectInfo tmp = {&debugObj, (size_t)Size, L.clone().release(), linfo};
            objectmap[Addr] = tmp;
        }

#else // pre-LLVM37
        uint64_t Addr;
        uint64_t Size;
        object::SymbolRef::Type SymbolType;
        StringRef sName;
#ifdef LLVM36
        uint64_t SectionAddr = 0;
#else
        bool isText;
#ifdef _OS_WINDOWS_
        uint64_t SectionAddr = 0;
#endif
#endif

#if defined(LLVM35)
        for (const object::SymbolRef &sym_iter : obj.symbols()) {
            sym_iter.getType(SymbolType);
            if (SymbolType != object::SymbolRef::ST_Function) continue;
            sym_iter.getSize(Size);
            sym_iter.getAddress(Addr);
            sym_iter.getSection(Section);
            if (Section == EndSection) continue;
#if defined(LLVM36)
            if (!Section->isText()) continue;
            Section->getName(sName);
            SectionAddr = L.getSectionLoadAddress(sName);
            Addr += SectionAddr;
#else
            if (Section->isText(isText) || !isText) continue;
#endif
            sym_iter.getName(sName);
#ifdef _OS_DARWIN_
#   if !defined(LLVM36)
            Addr = ((MCJIT*)jl_ExecutionEngine)->getSymbolAddress(sName, true);
            if (!Addr && sName[0] == '_') {
                Addr = ((MCJIT*)jl_ExecutionEngine)->getSymbolAddress(sName.substr(1), true);
            }
            if (!Addr) continue;
#   endif
#elif defined(_OS_WINDOWS_)
            uint64_t SectionSize = 0;
#   if defined(LLVM36)
            SectionSize = Section->getSize();
#   else
            Section->getAddress(SectionAddr);
            Section->getSize(SectionSize);
#   endif
            if (SectionAddrCheck)
                assert(SectionAddrCheck == SectionAddr);
            else
                SectionAddrCheck = SectionAddr;
            create_PRUNTIME_FUNCTION(
                   (uint8_t*)(intptr_t)Addr, (size_t)Size, sName,
                   (uint8_t*)(intptr_t)SectionAddr, (size_t)SectionSize, UnwindData);
#endif
            StringMap<jl_lambda_info_t*>::iterator linfo_it = linfo_in_flight.find(sName);
            jl_lambda_info_t *linfo = NULL;
            if (linfo_it != linfo_in_flight.end()) {
                linfo = linfo_it->second;
                linfo_in_flight.erase(linfo_it);
            }
            const object::ObjectFile *objfile =
#ifdef LLVM36
                &obj;
#else
                obj.getObjectFile();
#endif
            ObjectInfo tmp = {objfile, (size_t)Size,
#ifdef LLVM37
                L.clone().release(),
#elif defined(LLVM36)
                (size_t)SectionAddr,
#endif
#ifdef _OS_DARWIN_
                strndup(sName.data(), sName.size()),
#endif
                linfo
            };
            objectmap[Addr] = tmp;
        }
#else //LLVM34
        error_code itererr;
        object::symbol_iterator sym_iter = obj.begin_symbols();
        object::symbol_iterator sym_end = obj.end_symbols();
        for (; sym_iter != sym_end; sym_iter.increment(itererr)) {
            sym_iter->getType(SymbolType);
            if (SymbolType != object::SymbolRef::ST_Function) continue;
            sym_iter->getAddress(Addr);
            sym_iter->getSize(Size);

            ObjectInfo tmp = {obj.getObjectFile(), (size_t)Size};
            objectmap[Addr] = tmp;
        }
#endif
#endif
        uv_rwlock_wrunlock(&threadsafe);
    }
Example #22
0
bool Pattern::ParsePattern(StringRef PatternStr, SourceMgr &SM) {
  PatternLoc = SMLoc::getFromPointer(PatternStr.data());

  // Ignore trailing whitespace.
  while (!PatternStr.empty() &&
         (PatternStr.back() == ' ' || PatternStr.back() == '\t'))
    PatternStr = PatternStr.substr(0, PatternStr.size()-1);

  // Check that there is something on the line.
  if (PatternStr.empty()) {
    SM.PrintMessage(PatternLoc, "found empty check string with prefix '" +
                    CheckPrefix+":'", "error");
    return true;
  }

  // Check to see if this is a fixed string, or if it has regex pieces.
  if (PatternStr.size() < 2 ||
      (PatternStr.find("{{") == StringRef::npos &&
       PatternStr.find("[[") == StringRef::npos)) {
    FixedStr = PatternStr;
    return false;
  }

  // Paren value #0 is for the fully matched string.  Any new parenthesized
  // values add from their.
  unsigned CurParen = 1;

  // Otherwise, there is at least one regex piece.  Build up the regex pattern
  // by escaping scary characters in fixed strings, building up one big regex.
  while (!PatternStr.empty()) {
    // RegEx matches.
    if (PatternStr.size() >= 2 &&
        PatternStr[0] == '{' && PatternStr[1] == '{') {

      // Otherwise, this is the start of a regex match.  Scan for the }}.
      size_t End = PatternStr.find("}}");
      if (End == StringRef::npos) {
        SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()),
                        "found start of regex string with no end '}}'", "error");
        return true;
      }

      if (AddRegExToRegEx(PatternStr.substr(2, End-2), CurParen, SM))
        return true;
      PatternStr = PatternStr.substr(End+2);
      continue;
    }

    // Named RegEx matches.  These are of two forms: [[foo:.*]] which matches .*
    // (or some other regex) and assigns it to the FileCheck variable 'foo'. The
    // second form is [[foo]] which is a reference to foo.  The variable name
    // itself must be of the form "[a-zA-Z_][0-9a-zA-Z_]*", otherwise we reject
    // it.  This is to catch some common errors.
    if (PatternStr.size() >= 2 &&
        PatternStr[0] == '[' && PatternStr[1] == '[') {
      // Verify that it is terminated properly.
      size_t End = PatternStr.find("]]");
      if (End == StringRef::npos) {
        SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()),
                        "invalid named regex reference, no ]] found", "error");
        return true;
      }

      StringRef MatchStr = PatternStr.substr(2, End-2);
      PatternStr = PatternStr.substr(End+2);

      // Get the regex name (e.g. "foo").
      size_t NameEnd = MatchStr.find(':');
      StringRef Name = MatchStr.substr(0, NameEnd);

      if (Name.empty()) {
        SM.PrintMessage(SMLoc::getFromPointer(Name.data()),
                        "invalid name in named regex: empty name", "error");
        return true;
      }

      // Verify that the name is well formed.
      for (unsigned i = 0, e = Name.size(); i != e; ++i)
        if (Name[i] != '_' &&
            (Name[i] < 'a' || Name[i] > 'z') &&
            (Name[i] < 'A' || Name[i] > 'Z') &&
            (Name[i] < '0' || Name[i] > '9')) {
          SM.PrintMessage(SMLoc::getFromPointer(Name.data()+i),
                          "invalid name in named regex", "error");
          return true;
        }

      // Name can't start with a digit.
      if (isdigit(Name[0])) {
        SM.PrintMessage(SMLoc::getFromPointer(Name.data()),
                        "invalid name in named regex", "error");
        return true;
      }

      // Handle [[foo]].
      if (NameEnd == StringRef::npos) {
        VariableUses.push_back(std::make_pair(Name, RegExStr.size()));
        continue;
      }

      // Handle [[foo:.*]].
      VariableDefs.push_back(std::make_pair(Name, CurParen));
      RegExStr += '(';
      ++CurParen;

      if (AddRegExToRegEx(MatchStr.substr(NameEnd+1), CurParen, SM))
        return true;

      RegExStr += ')';
    }

    // Handle fixed string matches.
    // Find the end, which is the start of the next regex.
    size_t FixedMatchEnd = PatternStr.find("{{");
    FixedMatchEnd = std::min(FixedMatchEnd, PatternStr.find("[["));
    AddFixedStringToRegEx(PatternStr.substr(0, FixedMatchEnd), RegExStr);
    PatternStr = PatternStr.substr(FixedMatchEnd);
    continue;
  }

  return false;
}
Example #23
0
/// Check if this string starts with the given \p Prefix.
bool StringRef::startswith(StringRef pPrefix) const
{
  return (m_Length >= pPrefix.length() &&
         0 == compareMemory(m_Data, pPrefix.data(), pPrefix.length()));
}
Example #24
0
void Pattern::PrintFailureInfo(const SourceMgr &SM, StringRef Buffer,
                               const StringMap<StringRef> &VariableTable) const{
  // If this was a regular expression using variables, print the current
  // variable values.
  if (!VariableUses.empty()) {
    for (unsigned i = 0, e = VariableUses.size(); i != e; ++i) {
      StringRef Var = VariableUses[i].first;
      StringMap<StringRef>::const_iterator it = VariableTable.find(Var);
      SmallString<256> Msg;
      raw_svector_ostream OS(Msg);

      // Check for undefined variable references.
      if (it == VariableTable.end()) {
        OS << "uses undefined variable \"";
        OS.write_escaped(Var) << "\"";;
      } else {
        OS << "with variable \"";
        OS.write_escaped(Var) << "\" equal to \"";
        OS.write_escaped(it->second) << "\"";
      }

      SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), OS.str(), "note",
                      /*ShowLine=*/false);
    }
  }

  // Attempt to find the closest/best fuzzy match.  Usually an error happens
  // because some string in the output didn't exactly match. In these cases, we
  // would like to show the user a best guess at what "should have" matched, to
  // save them having to actually check the input manually.
  size_t NumLinesForward = 0;
  size_t Best = StringRef::npos;
  double BestQuality = 0;

  // Use an arbitrary 4k limit on how far we will search.
  for (size_t i = 0, e = std::min(size_t(4096), Buffer.size()); i != e; ++i) {
    if (Buffer[i] == '\n')
      ++NumLinesForward;

    // Patterns have leading whitespace stripped, so skip whitespace when
    // looking for something which looks like a pattern.
    if (Buffer[i] == ' ' || Buffer[i] == '\t')
      continue;

    // Compute the "quality" of this match as an arbitrary combination of the
    // match distance and the number of lines skipped to get to this match.
    unsigned Distance = ComputeMatchDistance(Buffer.substr(i), VariableTable);
    double Quality = Distance + (NumLinesForward / 100.);

    if (Quality < BestQuality || Best == StringRef::npos) {
      Best = i;
      BestQuality = Quality;
    }
  }

  // Print the "possible intended match here" line if we found something
  // reasonable and not equal to what we showed in the "scanning from here"
  // line.
  if (Best && Best != StringRef::npos && BestQuality < 50) {
      SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + Best),
                      "possible intended match here", "note");

    // FIXME: If we wanted to be really friendly we would show why the match
    // failed, as it can be hard to spot simple one character differences.
  }
}
Example #25
0
static void mergeInstrProfile(const WeightedFileVector &Inputs,
                              StringRef OutputFilename,
                              ProfileFormat OutputFormat, bool OutputSparse,
                              unsigned NumThreads) {
  if (OutputFilename.compare("-") == 0)
    exitWithError("Cannot write indexed profdata format to stdout.");

  if (OutputFormat != PF_Binary && OutputFormat != PF_Text)
    exitWithError("Unknown format is specified.");

  std::error_code EC;
  raw_fd_ostream Output(OutputFilename.data(), EC, sys::fs::F_None);
  if (EC)
    exitWithErrorCode(EC, OutputFilename);

  std::mutex ErrorLock;
  SmallSet<instrprof_error, 4> WriterErrorCodes;

  // If NumThreads is not specified, auto-detect a good default.
  if (NumThreads == 0)
    NumThreads = std::max(1U, std::min(std::thread::hardware_concurrency(),
                                       unsigned(Inputs.size() / 2)));

  // Initialize the writer contexts.
  SmallVector<std::unique_ptr<WriterContext>, 4> Contexts;
  for (unsigned I = 0; I < NumThreads; ++I)
    Contexts.emplace_back(llvm::make_unique<WriterContext>(
        OutputSparse, ErrorLock, WriterErrorCodes));

  if (NumThreads == 1) {
    for (const auto &Input : Inputs)
      loadInput(Input, Contexts[0].get());
  } else {
    ThreadPool Pool(NumThreads);

    // Load the inputs in parallel (N/NumThreads serial steps).
    unsigned Ctx = 0;
    for (const auto &Input : Inputs) {
      Pool.async(loadInput, Input, Contexts[Ctx].get());
      Ctx = (Ctx + 1) % NumThreads;
    }
    Pool.wait();

    // Merge the writer contexts together (~ lg(NumThreads) serial steps).
    unsigned Mid = Contexts.size() / 2;
    unsigned End = Contexts.size();
    assert(Mid > 0 && "Expected more than one context");
    do {
      for (unsigned I = 0; I < Mid; ++I)
        Pool.async(mergeWriterContexts, Contexts[I].get(),
                   Contexts[I + Mid].get());
      Pool.wait();
      if (End & 1) {
        Pool.async(mergeWriterContexts, Contexts[0].get(),
                   Contexts[End - 1].get());
        Pool.wait();
      }
      End = Mid;
      Mid /= 2;
    } while (Mid > 0);
  }

  // Handle deferred hard errors encountered during merging.
  for (std::unique_ptr<WriterContext> &WC : Contexts)
    if (WC->Err)
      exitWithError(std::move(WC->Err), WC->ErrWhence);

  InstrProfWriter &Writer = Contexts[0]->Writer;
  if (OutputFormat == PF_Text)
    Writer.writeText(Output);
  else
    Writer.write(Output);
}
Example #26
0
/// ReadCheckFile - Read the check file, which specifies the sequence of
/// expected strings.  The strings are added to the CheckStrings vector.
static bool ReadCheckFile(SourceMgr &SM,
                          std::vector<CheckString> &CheckStrings) {
  // Open the check file, and tell SourceMgr about it.
  std::string ErrorStr;
  MemoryBuffer *F =
    MemoryBuffer::getFileOrSTDIN(CheckFilename.c_str(), &ErrorStr);
  if (F == 0) {
    errs() << "Could not open check file '" << CheckFilename << "': "
           << ErrorStr << '\n';
    return true;
  }

  // If we want to canonicalize whitespace, strip excess whitespace from the
  // buffer containing the CHECK lines.
  if (!NoCanonicalizeWhiteSpace)
    F = CanonicalizeInputFile(F);

  SM.AddNewSourceBuffer(F, SMLoc());

  // Find all instances of CheckPrefix followed by : in the file.
  StringRef Buffer = F->getBuffer();

  std::vector<std::pair<SMLoc, Pattern> > NotMatches;

  while (1) {
    // See if Prefix occurs in the memory buffer.
    Buffer = Buffer.substr(Buffer.find(CheckPrefix));

    // If we didn't find a match, we're done.
    if (Buffer.empty())
      break;

    const char *CheckPrefixStart = Buffer.data();

    // When we find a check prefix, keep track of whether we find CHECK: or
    // CHECK-NEXT:
    bool IsCheckNext = false, IsCheckNot = false;

    // Verify that the : is present after the prefix.
    if (Buffer[CheckPrefix.size()] == ':') {
      Buffer = Buffer.substr(CheckPrefix.size()+1);
    } else if (Buffer.size() > CheckPrefix.size()+6 &&
               memcmp(Buffer.data()+CheckPrefix.size(), "-NEXT:", 6) == 0) {
      Buffer = Buffer.substr(CheckPrefix.size()+7);
      IsCheckNext = true;
    } else if (Buffer.size() > CheckPrefix.size()+5 &&
               memcmp(Buffer.data()+CheckPrefix.size(), "-NOT:", 5) == 0) {
      Buffer = Buffer.substr(CheckPrefix.size()+6);
      IsCheckNot = true;
    } else {
      Buffer = Buffer.substr(1);
      continue;
    }

    // Okay, we found the prefix, yay.  Remember the rest of the line, but
    // ignore leading and trailing whitespace.
    Buffer = Buffer.substr(Buffer.find_first_not_of(" \t"));

    // Scan ahead to the end of line.
    size_t EOL = Buffer.find_first_of("\n\r");

    // Remember the location of the start of the pattern, for diagnostics.
    SMLoc PatternLoc = SMLoc::getFromPointer(Buffer.data());

    // Parse the pattern.
    Pattern P;
    if (P.ParsePattern(Buffer.substr(0, EOL), SM))
      return true;

    Buffer = Buffer.substr(EOL);


    // Verify that CHECK-NEXT lines have at least one CHECK line before them.
    if (IsCheckNext && CheckStrings.empty()) {
      SM.PrintMessage(SMLoc::getFromPointer(CheckPrefixStart),
                      "found '"+CheckPrefix+"-NEXT:' without previous '"+
                      CheckPrefix+ ": line", "error");
      return true;
    }

    // Handle CHECK-NOT.
    if (IsCheckNot) {
      NotMatches.push_back(std::make_pair(SMLoc::getFromPointer(Buffer.data()),
                                          P));
      continue;
    }


    // Okay, add the string we captured to the output vector and move on.
    CheckStrings.push_back(CheckString(P,
                                       PatternLoc,
                                       IsCheckNext));
    std::swap(NotMatches, CheckStrings.back().NotStrings);
  }

  if (CheckStrings.empty()) {
    errs() << "error: no check strings found with prefix '" << CheckPrefix
           << ":'\n";
    return true;
  }

  if (!NotMatches.empty()) {
    errs() << "error: '" << CheckPrefix
           << "-NOT:' not supported after last check line.\n";
    return true;
  }

  return false;
}
Example #27
0
static void TranslateOptArg(Arg *A, llvm::opt::DerivedArgList &DAL,
                            bool SupportsForcingFramePointer,
                            const char *ExpandChar, const OptTable &Opts) {
  assert(A->getOption().matches(options::OPT__SLASH_O));

  StringRef OptStr = A->getValue();
  for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
    const char &OptChar = *(OptStr.data() + I);
    switch (OptChar) {
    default:
      break;
    case '1':
    case '2':
    case 'x':
    case 'd':
      if (&OptChar == ExpandChar) {
        if (OptChar == 'd') {
          DAL.AddFlagArg(A, Opts.getOption(options::OPT_O0));
        } else {
          if (OptChar == '1') {
            DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
          } else if (OptChar == '2' || OptChar == 'x') {
            DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
            DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
          }
          if (SupportsForcingFramePointer &&
              !DAL.hasArgNoClaim(options::OPT_fno_omit_frame_pointer))
            DAL.AddFlagArg(A,
                           Opts.getOption(options::OPT_fomit_frame_pointer));
          if (OptChar == '1' || OptChar == '2')
            DAL.AddFlagArg(A,
                           Opts.getOption(options::OPT_ffunction_sections));
        }
      }
      break;
    case 'b':
      if (I + 1 != E && isdigit(OptStr[I + 1])) {
        switch (OptStr[I + 1]) {
        case '0':
          DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_inline));
          break;
        case '1':
          DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_hint_functions));
          break;
        case '2':
          DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_functions));
          break;
        }
        ++I;
      }
      break;
    case 'g':
      break;
    case 'i':
      if (I + 1 != E && OptStr[I + 1] == '-') {
        ++I;
        DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_builtin));
      } else {
        DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
      }
      break;
    case 's':
      DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
      break;
    case 't':
      DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
      break;
    case 'y': {
      bool OmitFramePointer = true;
      if (I + 1 != E && OptStr[I + 1] == '-') {
        OmitFramePointer = false;
        ++I;
      }
      if (SupportsForcingFramePointer) {
        if (OmitFramePointer)
          DAL.AddFlagArg(A,
                         Opts.getOption(options::OPT_fomit_frame_pointer));
        else
          DAL.AddFlagArg(
              A, Opts.getOption(options::OPT_fno_omit_frame_pointer));
      } else {
        // Don't warn about /Oy- in 64-bit builds (where
        // SupportsForcingFramePointer is false).  The flag having no effect
        // there is a compiler-internal optimization, and people shouldn't have
        // to special-case their build files for 64-bit clang-cl.
        A->claim();
      }
      break;
    }
    }
  }
}
Example #28
0
int main(int argc, char **argv) {
  sys::PrintStackTraceOnErrorSignal();
  PrettyStackTraceProgram X(argc, argv);
  cl::ParseCommandLineOptions(argc, argv);

  SourceMgr SM;

  // Read the expected strings from the check file.
  std::vector<CheckString> CheckStrings;
  if (ReadCheckFile(SM, CheckStrings))
    return 2;

  // Open the file to check and add it to SourceMgr.
  std::string ErrorStr;
  MemoryBuffer *F =
    MemoryBuffer::getFileOrSTDIN(InputFilename.c_str(), &ErrorStr);
  if (F == 0) {
    errs() << "Could not open input file '" << InputFilename << "': "
           << ErrorStr << '\n';
    return true;
  }

  // Remove duplicate spaces in the input file if requested.
  if (!NoCanonicalizeWhiteSpace)
    F = CanonicalizeInputFile(F);

  SM.AddNewSourceBuffer(F, SMLoc());

  /// VariableTable - This holds all the current filecheck variables.
  StringMap<StringRef> VariableTable;

  // Check that we have all of the expected strings, in order, in the input
  // file.
  StringRef Buffer = F->getBuffer();

  const char *LastMatch = Buffer.data();

  for (unsigned StrNo = 0, e = CheckStrings.size(); StrNo != e; ++StrNo) {
    const CheckString &CheckStr = CheckStrings[StrNo];

    StringRef SearchFrom = Buffer;

    // Find StrNo in the file.
    size_t MatchLen = 0;
    Buffer = Buffer.substr(CheckStr.Pat.Match(Buffer, MatchLen, VariableTable));

    // If we didn't find a match, reject the input.
    if (Buffer.empty()) {
      PrintCheckFailed(SM, CheckStr, SearchFrom, VariableTable);
      return 1;
    }

    StringRef SkippedRegion(LastMatch, Buffer.data()-LastMatch);

    // If this check is a "CHECK-NEXT", verify that the previous match was on
    // the previous line (i.e. that there is one newline between them).
    if (CheckStr.IsCheckNext) {
      // Count the number of newlines between the previous match and this one.
      assert(LastMatch != F->getBufferStart() &&
             "CHECK-NEXT can't be the first check in a file");

      unsigned NumNewLines = CountNumNewlinesBetween(SkippedRegion);
      if (NumNewLines == 0) {
        SM.PrintMessage(CheckStr.Loc,
                    CheckPrefix+"-NEXT: is on the same line as previous match",
                        "error");
        SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()),
                        "'next' match was here", "note");
        SM.PrintMessage(SMLoc::getFromPointer(LastMatch),
                        "previous match was here", "note");
        return 1;
      }

      if (NumNewLines != 1) {
        SM.PrintMessage(CheckStr.Loc,
                        CheckPrefix+
                        "-NEXT: is not on the line after the previous match",
                        "error");
        SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()),
                        "'next' match was here", "note");
        SM.PrintMessage(SMLoc::getFromPointer(LastMatch),
                        "previous match was here", "note");
        return 1;
      }
    }

    // If this match had "not strings", verify that they don't exist in the
    // skipped region.
    for (unsigned ChunkNo = 0, e = CheckStr.NotStrings.size();
         ChunkNo != e; ++ChunkNo) {
      size_t MatchLen = 0;
      size_t Pos = CheckStr.NotStrings[ChunkNo].second.Match(SkippedRegion,
                                                             MatchLen,
                                                             VariableTable);
      if (Pos == StringRef::npos) continue;

      SM.PrintMessage(SMLoc::getFromPointer(LastMatch+Pos),
                      CheckPrefix+"-NOT: string occurred!", "error");
      SM.PrintMessage(CheckStr.NotStrings[ChunkNo].first,
                      CheckPrefix+"-NOT: pattern specified here", "note");
      return 1;
    }


    // Otherwise, everything is good.  Step over the matched text and remember
    // the position after the match as the end of the last match.
    Buffer = Buffer.substr(MatchLen);
    LastMatch = Buffer.data();
  }

  return 0;
}
Example #29
0
/// \brief Emit a code snippet and caret line.
///
/// This routine emits a single line's code snippet and caret line..
///
/// \param Loc The location for the caret.
/// \param Ranges The underlined ranges for this code snippet.
/// \param Hints The FixIt hints active for this diagnostic.
void TextDiagnostic::emitSnippetAndCaret(
    SourceLocation Loc, DiagnosticsEngine::Level Level,
    SmallVectorImpl<CharSourceRange>& Ranges,
    ArrayRef<FixItHint> Hints,
    const SourceManager &SM) {
  assert(Loc.isValid() && "must have a valid source location here");
  assert(Loc.isFileID() && "must have a file location here");

  // If caret diagnostics are enabled and we have location, we want to
  // emit the caret.  However, we only do this if the location moved
  // from the last diagnostic, if the last diagnostic was a note that
  // was part of a different warning or error diagnostic, or if the
  // diagnostic has ranges.  We don't want to emit the same caret
  // multiple times if one loc has multiple diagnostics.
  if (!DiagOpts->ShowCarets)
    return;
  if (Loc == LastLoc && Ranges.empty() && Hints.empty() &&
      (LastLevel != DiagnosticsEngine::Note || Level == LastLevel))
    return;

  // Decompose the location into a FID/Offset pair.
  std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
  FileID FID = LocInfo.first;
  unsigned FileOffset = LocInfo.second;

  // Get information about the buffer it points into.
  bool Invalid = false;
  StringRef BufData = SM.getBufferData(FID, &Invalid);
  if (Invalid)
    return;

  const char *BufStart = BufData.data();
  const char *BufEnd = BufStart + BufData.size();

  unsigned LineNo = SM.getLineNumber(FID, FileOffset);
  unsigned ColNo = SM.getColumnNumber(FID, FileOffset);
  
  // Arbitrarily stop showing snippets when the line is too long.
  static const size_t MaxLineLengthToPrint = 4096;
  if (ColNo > MaxLineLengthToPrint)
    return;

  // Rewind from the current position to the start of the line.
  const char *TokPtr = BufStart+FileOffset;
  const char *LineStart = TokPtr-ColNo+1; // Column # is 1-based.

  // Compute the line end.  Scan forward from the error position to the end of
  // the line.
  const char *LineEnd = TokPtr;
  while (*LineEnd != '\n' && *LineEnd != '\r' && LineEnd != BufEnd)
    ++LineEnd;

  // Arbitrarily stop showing snippets when the line is too long.
  if (size_t(LineEnd - LineStart) > MaxLineLengthToPrint)
    return;

  // Trim trailing null-bytes.
  StringRef Line(LineStart, LineEnd - LineStart);
  while (Line.size() > ColNo && Line.back() == '\0')
    Line = Line.drop_back();

  // Copy the line of code into an std::string for ease of manipulation.
  std::string SourceLine(Line.begin(), Line.end());

  // Build the byte to column map.
  const SourceColumnMap sourceColMap(SourceLine, DiagOpts->TabStop);

  // Create a line for the caret that is filled with spaces that is the same
  // number of columns as the line of source code.
  std::string CaretLine(sourceColMap.columns(), ' ');

  // Highlight all of the characters covered by Ranges with ~ characters.
  for (SmallVectorImpl<CharSourceRange>::iterator I = Ranges.begin(),
                                                  E = Ranges.end();
       I != E; ++I)
    highlightRange(*I, LineNo, FID, sourceColMap, CaretLine, SM, LangOpts);

  // Next, insert the caret itself.
  ColNo = sourceColMap.byteToContainingColumn(ColNo-1);
  if (CaretLine.size()<ColNo+1)
    CaretLine.resize(ColNo+1, ' ');
  CaretLine[ColNo] = '^';

  std::string FixItInsertionLine = buildFixItInsertionLine(LineNo,
                                                           sourceColMap,
                                                           Hints, SM,
                                                           DiagOpts.get());

  // If the source line is too long for our terminal, select only the
  // "interesting" source region within that line.
  unsigned Columns = DiagOpts->MessageLength;
  if (Columns)
    selectInterestingSourceRegion(SourceLine, CaretLine, FixItInsertionLine,
                                  Columns, sourceColMap);

  // If we are in -fdiagnostics-print-source-range-info mode, we are trying
  // to produce easily machine parsable output.  Add a space before the
  // source line and the caret to make it trivial to tell the main diagnostic
  // line from what the user is intended to see.
  if (DiagOpts->ShowSourceRanges) {
    SourceLine = ' ' + SourceLine;
    CaretLine = ' ' + CaretLine;
  }

  // Finally, remove any blank spaces from the end of CaretLine.
  while (CaretLine[CaretLine.size()-1] == ' ')
    CaretLine.erase(CaretLine.end()-1);

  // Emit what we have computed.
  emitSnippet(SourceLine);

  if (DiagOpts->ShowColors)
    OS.changeColor(caretColor, true);
  OS << CaretLine << '\n';
  if (DiagOpts->ShowColors)
    OS.resetColor();

  if (!FixItInsertionLine.empty()) {
    if (DiagOpts->ShowColors)
      // Print fixit line in color
      OS.changeColor(fixitColor, false);
    if (DiagOpts->ShowSourceRanges)
      OS << ' ';
    OS << FixItInsertionLine << '\n';
    if (DiagOpts->ShowColors)
      OS.resetColor();
  }

  // Print out any parseable fixit information requested by the options.
  emitParseableFixits(Hints, SM);
}
Example #30
0
bool swift::omitNeedlessWords(StringRef &baseName,
                              MutableArrayRef<StringRef> argNames,
                              StringRef firstParamName,
                              OmissionTypeName resultType,
                              OmissionTypeName contextType,
                              ArrayRef<OmissionTypeName> paramTypes,
                              bool returnsSelf,
                              bool isProperty,
                              const InheritedNameSet *allPropertyNames,
                              StringScratchSpace &scratch) {
  bool anyChanges = false;

  /// Local function that lowercases all of the base names and
  /// argument names before returning.
  auto lowercaseAcronymsForReturn = [&] {
    StringRef newBaseName = toLowercaseWordAndAcronym(baseName, scratch);
    if (baseName.data() != newBaseName.data()) {
      baseName = newBaseName;
      anyChanges = true;
    }

    for (StringRef &argName : argNames) {
      StringRef newArgName = toLowercaseWordAndAcronym(argName, scratch);
      if (argName.data() != newArgName.data()) {
        argName = newArgName;
        anyChanges = true;
      }
    }

    return anyChanges;
  };

  // If the result type matches the context, remove the context type from the
  // prefix of the name.
  bool resultTypeMatchesContext = returnsSelf || (resultType == contextType);
  if (resultTypeMatchesContext) {
    StringRef newBaseName = omitNeedlessWordsFromPrefix(baseName, contextType,
                                                        scratch);
    if (newBaseName != baseName) {
      baseName = newBaseName;
      anyChanges = true;
    }
  }

  // Treat zero-parameter methods and properties the same way.
  if (paramTypes.empty()) {
    if (resultTypeMatchesContext) {
      StringRef newBaseName = ::omitNeedlessWords(
                                baseName,
                                returnsSelf ? contextType : resultType,
                                NameRole::Property,
                                allPropertyNames,
                                scratch);
      if (newBaseName != baseName) {
        baseName = newBaseName;
        anyChanges = true;
      }
    }

    // Boolean properties should start with "is", unless their
    // first word already implies a Boolean result.
    if (resultType.isBoolean() && isProperty &&
        !nameIndicatesBooleanResult(baseName)) {
      SmallString<32> newName("is");
      camel_case::appendSentenceCase(newName, baseName);
      baseName = scratch.copyString(newName);
      anyChanges = true;
    }

    return lowercaseAcronymsForReturn();
  }

  // Omit needless words based on parameter types.
  for (unsigned i = 0, n = argNames.size(); i != n; ++i) {
    // If there is no corresponding parameter, there is nothing to
    // omit.
    if (i >= paramTypes.size()) continue;

    // Omit needless words based on the type of the parameter.
    NameRole role = i > 0 ? NameRole::SubsequentParameter
      : argNames[0].empty() ? NameRole::BaseName
      : NameRole::FirstParameter;

    // Omit needless words from the name.
    StringRef name = role == NameRole::BaseName ? baseName : argNames[i];
    StringRef newName = ::omitNeedlessWords(name, paramTypes[i], role,
                                            role == NameRole::BaseName 
                                              ? allPropertyNames
                                              : nullptr,
                                            scratch);

    // Did the name change?
    if (name != newName)
      anyChanges = true;

    // If the first parameter has a default argument, and there is a
    // preposition in the base name, split the base name at that preposition.
    if (role == NameRole::BaseName && argNames[0].empty() &&
        paramTypes[0].hasDefaultArgument()) {
      // Scan backwards for a preposition.
      auto nameWords = camel_case::getWords(newName);
      auto nameWordRevIter = nameWords.rbegin(),
        nameWordRevIterEnd = nameWords.rend();
      bool found = false, done = false;
      while (nameWordRevIter != nameWordRevIterEnd && !done) {
        switch (getPartOfSpeech(*nameWordRevIter)) {
        case PartOfSpeech::Preposition:
          found = true;
          done = true;
          break;

        case PartOfSpeech::Verb:
        case PartOfSpeech::Gerund:
          // Don't skip over verbs or gerunds.
          done = true;
          break;

        case PartOfSpeech::Unknown:
        case PartOfSpeech::AuxiliaryVerb:
          ++nameWordRevIter;
          break;
        }
      }

      // If we found a split point that's not at the beginning of the
      // name, split there.
      if (found) {
        ++nameWordRevIter;
        unsigned splitPos = nameWordRevIter.base().getPosition();
        if (splitPos > 0) {
          unsigned afterSplitPos = splitPos;

          // Create a first argument name with the remainder of the base name,
          // lowercased. If we would end up with a vacuous name, go
          // back and get the original.
          StringRef newArgName = newName.substr(afterSplitPos);
          if (isVacuousName(newArgName)) {
            size_t pos = name.rfind(newArgName);
            newArgName = name.substr(pos);
          }

          // If there is a leading "with" on the first argument, drop it.
          if (newArgName.size() > 4 &&
              camel_case::sameWordIgnoreFirstCase(
                camel_case::getFirstWord(newArgName),
                "with")) {
            newArgName = newArgName.substr(4);
          }

          argNames[0] = toLowercaseWord(newArgName, scratch);

          // Update the base name by splitting at the preposition.
          newName = newName.substr(0, splitPos);

          anyChanges = true;
        }
      }
    }

    if (name == newName) continue;

    // Record this change.
    if (role == NameRole::BaseName) {
      baseName = newName;
    } else {
      argNames[i] = newName;
    }
  }

  return lowercaseAcronymsForReturn();
}