コード例 #1
0
static void mergeInstrProfile(const cl::list<std::string> &Inputs,
                              StringRef OutputFilename) {
  if (OutputFilename.compare("-") == 0)
    exitWithError("Cannot write indexed profdata format to stdout.");

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

  InstrProfWriter Writer;
  for (const auto &Filename : Inputs) {
    auto ReaderOrErr = InstrProfReader::create(Filename);
    if (std::error_code ec = ReaderOrErr.getError())
      exitWithError(ec.message(), Filename);

    auto Reader = std::move(ReaderOrErr.get());
    for (auto &I : *Reader)
      if (std::error_code EC = Writer.addRecord(std::move(I)))
        errs() << Filename << ": " << I.Name << ": " << EC.message() << "\n";
    if (Reader->hasError())
      exitWithError(Reader->getError().message(), Filename);
  }
  Writer.write(Output);
}
コード例 #2
0
int FunctionComparator::cmpMem(StringRef L, StringRef R) const {
  // Prevent heavy comparison, compare sizes first.
  if (int Res = cmpNumbers(L.size(), R.size()))
    return Res;

  // Compare strings lexicographically only when it is necessary: only when
  // strings are equal in size.
  return L.compare(R);
}
コード例 #3
0
bool clang::operator<(const CodeCompletionResult &X, 
                      const CodeCompletionResult &Y) {
  std::string XSaved, YSaved;
  StringRef XStr = getOrderedName(X, XSaved);
  StringRef YStr = getOrderedName(Y, YSaved);
  int cmp = XStr.compare_lower(YStr);
  if (cmp)
    return cmp < 0;
  
  // If case-insensitive comparison fails, try case-sensitive comparison.
  cmp = XStr.compare(YStr);
  if (cmp)
    return cmp < 0;
  
  return false;
}
コード例 #4
0
ファイル: llvm-profdata.cpp プロジェクト: juanmaneo/llvm
static void mergeInstrProfile(const WeightedFileVector &Inputs,
                              StringRef OutputFilename,
                              ProfileFormat OutputFormat, bool OutputSparse) {
  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);

  InstrProfWriter Writer(OutputSparse);
  SmallSet<instrprof_error, 4> WriterErrorCodes;
  for (const auto &Input : Inputs) {
    auto ReaderOrErr = InstrProfReader::create(Input.Filename);
    if (Error E = ReaderOrErr.takeError())
      exitWithError(std::move(E), Input.Filename);

    auto Reader = std::move(ReaderOrErr.get());
    bool IsIRProfile = Reader->isIRLevelProfile();
    if (Writer.setIsIRLevelProfile(IsIRProfile))
      exitWithError("Merge IR generated profile with Clang generated profile.");

    for (auto &I : *Reader) {
      if (Error E = Writer.addRecord(std::move(I), Input.Weight)) {
        // Only show hint the first time an error occurs.
        instrprof_error IPE = InstrProfError::take(std::move(E));
        bool firstTime = WriterErrorCodes.insert(IPE).second;
        handleMergeWriterError(make_error<InstrProfError>(IPE), Input.Filename,
                               I.Name, firstTime);
      }
    }
    if (Reader->hasError())
      exitWithError(Reader->getError(), Input.Filename);
  }
  if (OutputFormat == PF_Text)
    Writer.writeText(Output);
  else
    Writer.write(Output);
}
コード例 #5
0
ファイル: LLILCJit.cpp プロジェクト: manu-silicon/llilc
void ObjectLoadListener::recordRelocations(
    const ObjectFile &Obj, const RuntimeDyld::LoadedObjectInfo &L) {
  for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end();
       SI != SE; ++SI) {
    section_iterator Section = SI->getRelocatedSection();

    if (Section == SE) {
      continue;
    }

    StringRef SectionName;
    std::error_code ErrorCode = Section->getName(SectionName);
    if (ErrorCode) {
      assert(false && ErrorCode.message().c_str());
    }

    if (SectionName.startswith(".debug") ||
        SectionName.startswith(".rela.debug") ||
        !SectionName.compare(".pdata") || SectionName.startswith(".eh_frame") ||
        SectionName.startswith(".rela.eh_frame")) {
      // Skip sections whose contents are not directly reported to the EE
      continue;
    }

    relocation_iterator I = SI->relocation_begin();
    relocation_iterator E = SI->relocation_end();

    for (; I != E; ++I) {
      symbol_iterator Symbol = I->getSymbol();
      assert(Symbol != Obj.symbol_end());
      ErrorOr<section_iterator> SymbolSectionOrErr = Symbol->getSection();
      assert(!SymbolSectionOrErr.getError());
      object::section_iterator SymbolSection = *SymbolSectionOrErr;
      const bool IsExtern = SymbolSection == Obj.section_end();
      uint64_t RelType = I->getType();
      uint64_t Offset = I->getOffset();
      uint8_t *RelocationTarget;
      if (IsExtern) {
        // This is an external symbol. Verify that it's one we created for
        // a global variable and report the relocation via Jit interface.
        ErrorOr<StringRef> NameOrError = Symbol->getName();
        assert(NameOrError);
        StringRef TargetName = NameOrError.get();
        auto MapIter = Context->NameToHandleMap.find(TargetName);
        if (MapIter == Context->NameToHandleMap.end()) {
          // The xdata gets a pointer to our personality routine, which we
          // dummied up.  We can safely skip it since the EE isn't actually
          // going to use the value (it inserts the correct one before handing
          // the xdata off to the OS).
          assert(!TargetName.compare("ProcessCLRException"));
          assert(SectionName.startswith(".xdata"));
          continue;
        } else {
          assert(MapIter->second == Context->NameToHandleMap[TargetName]);
          RelocationTarget = (uint8_t *)MapIter->second;
        }
      } else {
        RelocationTarget = (uint8_t *)(L.getSectionLoadAddress(*SymbolSection) +
                                       Symbol->getValue());
      }

      uint64_t Addend = 0;
      uint64_t EERelType = getRelocationType(RelType);
      uint64_t SectionAddress = L.getSectionLoadAddress(*Section);
      assert(SectionAddress != 0);
      uint8_t *FixupAddress = (uint8_t *)(SectionAddress + Offset);

      if (Obj.isELF()) {
        // Addend is part of the relocation
        ELFRelocationRef ElfReloc(*I);
        ErrorOr<uint64_t> ElfAddend = ElfReloc.getAddend();
        assert(!ElfAddend.getError());
        Addend = ElfAddend.get();
      } else {
        // Addend is read from the location to be fixed up
        Addend = getRelocationAddend(RelType, FixupAddress);
      }

      Context->JitInfo->recordRelocation(FixupAddress,
                                         RelocationTarget + Addend, EERelType);
    }
  }
}
コード例 #6
0
ファイル: MachODump.cpp プロジェクト: Abocer/android-4.2_r1
void llvm::DisassembleInputMachO(StringRef Filename) {
  OwningPtr<MemoryBuffer> Buff;

  if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buff)) {
    errs() << "llvm-objdump: " << Filename << ": " << ec.message() << "\n";
    return;
  }

  OwningPtr<MachOObjectFile> MachOOF(static_cast<MachOObjectFile*>(
        ObjectFile::createMachOObjectFile(Buff.take())));
  MachOObject *MachOObj = MachOOF->getObject();

  const Target *TheTarget = GetTarget(MachOObj);
  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 MCAsmInfo> AsmInfo(TheTarget->createMCAsmInfo(TripleName));
  OwningPtr<const MCSubtargetInfo>
    STI(TheTarget->createMCSubtargetInfo(TripleName, "", ""));
  OwningPtr<const MCDisassembler> DisAsm(TheTarget->createMCDisassembler(*STI));
  OwningPtr<const MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName));
  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";

  const macho::Header &Header = MachOObj->getHeader();

  const MachOObject::LoadCommandInfo *SymtabLCI = 0;
  // First, find the symbol table segment.
  for (unsigned i = 0; i != Header.NumLoadCommands; ++i) {
    const MachOObject::LoadCommandInfo &LCI = MachOObj->getLoadCommandInfo(i);
    if (LCI.Command.Type == macho::LCT_Symtab) {
      SymtabLCI = &LCI;
      break;
    }
  }

  // Read and register the symbol table data.
  InMemoryStruct<macho::SymtabLoadCommand> SymtabLC;
  if (SymtabLCI) {
    MachOObj->ReadSymtabLoadCommand(*SymtabLCI, SymtabLC);
    MachOObj->RegisterStringTable(*SymtabLC);
  }

  std::vector<SectionRef> Sections;
  std::vector<SymbolRef> Symbols;
  SmallVector<uint64_t, 8> FoundFns;

  getSectionsAndSymbols(Header, MachOOF.get(), &SymtabLC, Sections, Symbols,
                        FoundFns);

  // Make a copy of the unsorted symbol list. FIXME: duplication
  std::vector<SymbolRef> UnsortedSymbols(Symbols);
  // Sort the symbols by address, just in case they didn't come in that way.
  std::sort(Symbols.begin(), Symbols.end(), SymbolSorter());

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

  StringRef DebugAbbrevSection, DebugInfoSection, DebugArangesSection,
            DebugLineSection, DebugStrSection;
  OwningPtr<DIContext> diContext;
  OwningPtr<MachOObjectFile> DSYMObj;
  MachOObject *DbgInfoObj = MachOObj;
  // Try to find debug info and set up the DIContext for it.
  if (UseDbg) {
    ArrayRef<SectionRef> DebugSections = Sections;
    std::vector<SectionRef> DSYMSections;

    // 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.c_str(), Buf)) {
        errs() << "llvm-objdump: " << Filename << ": " << ec.message() << '\n';
        return;
      }
      DSYMObj.reset(static_cast<MachOObjectFile*>(
            ObjectFile::createMachOObjectFile(Buf.take())));
      const macho::Header &Header = DSYMObj->getObject()->getHeader();

      std::vector<SymbolRef> Symbols;
      SmallVector<uint64_t, 8> FoundFns;
      getSectionsAndSymbols(Header, DSYMObj.get(), 0, DSYMSections, Symbols,
                            FoundFns);
      DebugSections = DSYMSections;
      DbgInfoObj = DSYMObj.get()->getObject();
    }

    // Find the named debug info sections.
    for (unsigned SectIdx = 0; SectIdx != DebugSections.size(); SectIdx++) {
      StringRef SectName;
      if (!DebugSections[SectIdx].getName(SectName)) {
        if (SectName.equals("__DWARF,__debug_abbrev"))
          DebugSections[SectIdx].getContents(DebugAbbrevSection);
        else if (SectName.equals("__DWARF,__debug_info"))
          DebugSections[SectIdx].getContents(DebugInfoSection);
        else if (SectName.equals("__DWARF,__debug_aranges"))
          DebugSections[SectIdx].getContents(DebugArangesSection);
        else if (SectName.equals("__DWARF,__debug_line"))
          DebugSections[SectIdx].getContents(DebugLineSection);
        else if (SectName.equals("__DWARF,__debug_str"))
          DebugSections[SectIdx].getContents(DebugStrSection);
      }
    }

    // Setup the DIContext.
    diContext.reset(DIContext::getDWARFContext(DbgInfoObj->isLittleEndian(),
                                               DebugInfoSection,
                                               DebugAbbrevSection,
                                               DebugArangesSection,
                                               DebugLineSection,
                                               DebugStrSection));
  }

  FunctionMapTy FunctionMap;
  FunctionListTy Functions;

  for (unsigned SectIdx = 0; SectIdx != Sections.size(); SectIdx++) {
    StringRef SectName;
    if (Sections[SectIdx].getName(SectName) ||
        SectName.compare("__TEXT,__text"))
      continue; // Skip non-text sections

    // Insert the functions from the function starts segment into our map.
    uint64_t VMAddr;
    Sections[SectIdx].getAddress(VMAddr);
    for (unsigned i = 0, e = FoundFns.size(); i != e; ++i) {
      StringRef SectBegin;
      Sections[SectIdx].getContents(SectBegin);
      uint64_t Offset = (uint64_t)SectBegin.data();
      FunctionMap.insert(std::make_pair(VMAddr + FoundFns[i]-Offset,
                                        (MCFunction*)0));
    }

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

    // Parse relocations.
    std::vector<std::pair<uint64_t, SymbolRef> > Relocs;
    error_code ec;
    for (relocation_iterator RI = Sections[SectIdx].begin_relocations(),
         RE = Sections[SectIdx].end_relocations(); RI != RE; RI.increment(ec)) {
      uint64_t RelocOffset, SectionAddress;
      RI->getAddress(RelocOffset);
      Sections[SectIdx].getAddress(SectionAddress);
      RelocOffset -= SectionAddress;

      SymbolRef RelocSym;
      RI->getSymbol(RelocSym);

      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;

      if (!CFG) {
        // Normal disassembly, print addresses, bytes and mnemonic form.
        StringRef SymName;
        Symbols[SymIdx].getName(SymName);

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

          if (DisAsm->getInstruction(Inst, Size, memoryObject, Index,
                                     DebugOut, nulls())) {
            uint64_t SectAddress = 0;
            Sections[SectIdx].getAddress(SectAddress);
            outs() << format("%8" PRIx64 ":\t", SectAddress + Index);

            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
          }
        }
      } else {
        // Create CFG and use it for disassembly.
        StringRef SymName;
        Symbols[SymIdx].getName(SymName);
        createMCFunctionAndSaveCalls(
            SymName, DisAsm.get(), memoryObject, Start, End,
            InstrAnalysis.get(), Start, DebugOut, FunctionMap, Functions);
      }
    }
    if (!CFG && !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
        }
      }
    }

    if (CFG) {
      if (!symbolTableWorked) {
        // Reading the symbol table didn't work, create a big __TEXT symbol.
        uint64_t SectSize = 0, SectAddress = 0;
        Sections[SectIdx].getSize(SectSize);
        Sections[SectIdx].getAddress(SectAddress);
        createMCFunctionAndSaveCalls("__TEXT", DisAsm.get(), memoryObject,
                                     0, SectSize,
                                     InstrAnalysis.get(),
                                     SectAddress, DebugOut,
                                     FunctionMap, Functions);
      }
      for (std::map<uint64_t, MCFunction*>::iterator mi = FunctionMap.begin(),
           me = FunctionMap.end(); mi != me; ++mi)
        if (mi->second == 0) {
          // Create functions for the remaining callees we have gathered,
          // but we didn't find a name for them.
          uint64_t SectSize = 0;
          Sections[SectIdx].getSize(SectSize);

          SmallVector<uint64_t, 16> Calls;
          MCFunction f =
            MCFunction::createFunctionFromMC("unknown", DisAsm.get(),
                                             memoryObject, mi->first,
                                             SectSize,
                                             InstrAnalysis.get(), DebugOut,
                                             Calls);
          Functions.push_back(f);
          mi->second = &Functions.back();
          for (unsigned i = 0, e = Calls.size(); i != e; ++i) {
            std::pair<uint64_t, MCFunction*> p(Calls[i], (MCFunction*)0);
            if (FunctionMap.insert(p).second)
              mi = FunctionMap.begin();
          }
        }

      DenseSet<uint64_t> PrintedBlocks;
      for (unsigned ffi = 0, ffe = Functions.size(); ffi != ffe; ++ffi) {
        MCFunction &f = Functions[ffi];
        for (MCFunction::iterator fi = f.begin(), fe = f.end(); fi != fe; ++fi){
          if (!PrintedBlocks.insert(fi->first).second)
            continue; // We already printed this block.

          // We assume a block has predecessors when it's the first block after
          // a symbol.
          bool hasPreds = FunctionMap.find(fi->first) != FunctionMap.end();

          // See if this block has predecessors.
          // FIXME: Slow.
          for (MCFunction::iterator pi = f.begin(), pe = f.end(); pi != pe;
              ++pi)
            if (pi->second.contains(fi->first)) {
              hasPreds = true;
              break;
            }

          uint64_t SectSize = 0, SectAddress;
          Sections[SectIdx].getSize(SectSize);
          Sections[SectIdx].getAddress(SectAddress);

          // No predecessors, this is a data block. Print as .byte directives.
          if (!hasPreds) {
            uint64_t End = llvm::next(fi) == fe ? SectSize :
                                                  llvm::next(fi)->first;
            outs() << "# " << End-fi->first << " bytes of data:\n";
            for (unsigned pos = fi->first; pos != End; ++pos) {
              outs() << format("%8x:\t", SectAddress + pos);
              DumpBytes(StringRef(Bytes.data() + pos, 1));
              outs() << format("\t.byte 0x%02x\n", (uint8_t)Bytes[pos]);
            }
            continue;
          }

          if (fi->second.contains(fi->first)) // Print a header for simple loops
            outs() << "# Loop begin:\n";

          DILineInfo lastLine;
          // Walk over the instructions and print them.
          for (unsigned ii = 0, ie = fi->second.getInsts().size(); ii != ie;
               ++ii) {
            const MCDecodedInst &Inst = fi->second.getInsts()[ii];

            // If there's a symbol at this address, print its name.
            if (FunctionMap.find(SectAddress + Inst.Address) !=
                FunctionMap.end())
              outs() << FunctionMap[SectAddress + Inst.Address]-> getName()
                     << ":\n";

            outs() << format("%8" PRIx64 ":\t", SectAddress + Inst.Address);
            DumpBytes(StringRef(Bytes.data() + Inst.Address, Inst.Size));

            if (fi->second.contains(fi->first)) // Indent simple loops.
              outs() << '\t';

            IP->printInst(&Inst.Inst, outs(), "");

            // Look for relocations inside this instructions, if there is one
            // print its target and additional information if available.
            for (unsigned j = 0; j != Relocs.size(); ++j)
              if (Relocs[j].first >= SectAddress + Inst.Address &&
                  Relocs[j].first < SectAddress + Inst.Address + Inst.Size) {
                StringRef SymName;
                uint64_t Addr;
                Relocs[j].second.getAddress(Addr);
                Relocs[j].second.getName(SymName);

                outs() << "\t# " << SymName << ' ';
                DumpAddress(Addr, Sections, MachOObj, outs());
              }

            // If this instructions contains an address, see if we can evaluate
            // it and print additional information.
            uint64_t targ = InstrAnalysis->evaluateBranch(Inst.Inst,
                                                          Inst.Address,
                                                          Inst.Size);
            if (targ != -1ULL)
              DumpAddress(targ, Sections, MachOObj, outs());

            // Print debug info.
            if (diContext) {
              DILineInfo dli =
                diContext->getLineInfoForAddress(SectAddress + Inst.Address);
              // 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';
          }
        }

        emitDOTFile((f.getName().str() + ".dot").c_str(), f, IP.get());
      }
    }
  }
}
コード例 #7
0
ファイル: helper_call_modifier.cpp プロジェクト: 3a9LL/panda
int main(int argc, char **argv){
    // Load the bitcode
    cl::ParseCommandLineOptions(argc, argv, "helper_call_modifier\n");
    SMDiagnostic Err;     
    LLVMContext &Context = getGlobalContext();
    Module *Mod = ParseIRFile(InputFile, Err, Context);
    if (!Mod) {
        Err.print(argv[0], errs());
        exit(1);
    }
    
    /*
     * This iterates through the list of functions, copies/renames, and deletes
     * the original function.  This is how we have to do it with the while loop
     * because of how the LLVM function list is implemented.
     */
    Module::iterator i = Mod->begin();
    while (i != Mod->end()){
        Function *f = i;
        i++;
        
        Module *m = f->getParent();
        assert(m);
        if (!f->isDeclaration()){ // internal functions only
            StringRef fname = f->getName();
            if (!fname.compare("__ldb_mmu")
                    || !fname.compare("__ldw_mmu")
                    || !fname.compare("__ldl_mmu")
                    || !fname.compare("__ldq_mmu")
                    || !fname.compare("__stb_mmu")
                    || !fname.compare("__stw_mmu")
                    || !fname.compare("__stl_mmu")
                    || !fname.compare("__stq_mmu")){

                /* Replace LLVM memory functions with ASM panda (logging) memory
                 * functions and delete original.  For example, we want to call
                 * out of the LLVM module to __ldb_mmu_panda().
                 */
                Function *pandaFunc =
                    m->getFunction(StringRef(f->getName().str() + "_panda"));
                assert(pandaFunc);
                if (!pandaFunc->isDeclaration()){
                    pandaFunc->deleteBody();
                }
                f->replaceAllUsesWith(pandaFunc);
                f->eraseFromParent();
            }
            else if (!fname.compare("slow_ldb_mmu")
                    || !fname.compare("slow_ldw_mmu")
                    || !fname.compare("slow_ldl_mmu")
                    || !fname.compare("slow_ldq_mmu")
                    || !fname.compare("slow_stb_mmu")
                    || !fname.compare("slow_stw_mmu")
                    || !fname.compare("slow_stl_mmu")
                    || !fname.compare("slow_stq_mmu")
                    || !fname.compare("slow_ldb_mmu_panda")
                    || !fname.compare("slow_ldw_mmu_panda")
                    || !fname.compare("slow_ldl_mmu_panda")
                    || !fname.compare("slow_ldq_mmu_panda")
                    || !fname.compare("slow_stb_mmu_panda")
                    || !fname.compare("slow_stw_mmu_panda")
                    || !fname.compare("slow_stl_mmu_panda")
                    || !fname.compare("slow_stq_mmu_panda")){

                /* These functions are just artifacts, and are only contained
                 * within the previous functions.  We want these deleted from
                 * the LLVM module too, this is just kind of a hacky way to make
                 * sure the functions are deleted in the right order without
                 * making LLVM angry.
                 */
                if (f->hasNUsesOrMore(3)){
                    m->getFunctionList().remove(f);
                    m->getFunctionList().push_back(f);
                    continue;
                }
                else {
                    f->eraseFromParent();
                }
            }
            else {
                ValueToValueMapTy VMap;
                Function *newFunc = CloneFunction(f, VMap, false);
                std::string origName = f->getName();
                std::string newName = origName.append("_llvm");
                newFunc->setName(newName);
                /*
                 * XXX: We need to remove stack smash protection from helper
                 * functions that are to be compiled with the JIT.  There is a bug
                 * in LLVM 3.0 that causes the JIT to generate stack protection code
                 * that causes the program to segfault.  More information available
                 * here: http://llvm.org/bugs/show_bug.cgi?id=11089
                 */
                const AttributeSet AS = newFunc->getAttributes();
                newFunc->setAttributes(AS.removeAttribute(newFunc->getContext(),
                    AttributeSet::FunctionIndex, Attribute::StackProtectReq));
                // push to the front so the iterator doesn't see them again
                m->getFunctionList().push_front(newFunc);
                f->replaceAllUsesWith(newFunc);
                f->eraseFromParent();
            }
        }
    }
    
    // Verify the new bitcode and write it out, printing errors if necessary
    std::string errstring;
    verifyModule(*Mod, PrintMessageAction, &errstring);
    raw_fd_ostream *fstream = new raw_fd_ostream(OutputFile.c_str(), errstring);
    WriteBitcodeToFile(Mod, *fstream);
    printf("%s", errstring.c_str());
    fstream->close();

    return 0;
}
コード例 #8
0
ファイル: StringRef.cpp プロジェクト: sconger/cupcake
bool operator>=(const StringRef strRef, const char* cstr) {
    return strRef.compare(StringRef(cstr)) >= 0;
}
コード例 #9
0
ファイル: StringRef.cpp プロジェクト: sconger/cupcake
bool operator>=(const StringRef strRef1, const StringRef strRef2) {
    return strRef1.compare(strRef2) >= 0;
}
コード例 #10
0
ファイル: StringRef.cpp プロジェクト: sconger/cupcake
bool operator<(const StringRef strRef1, const StringRef strRef2) {
    return strRef1.compare(strRef2) < 0;
}
コード例 #11
0
ファイル: SSPParser.cpp プロジェクト: jholewinski/overtile
int SSPParser::getNextToken(void *Val) {
  YYSTYPE *Value = static_cast<YYSTYPE*>(Val);

  StringRef    BufferData = Buf->getBuffer();
  const char  *Data       = BufferData.data();
  const char*  CurCh      = Data+CurPos;

  while (CurPos < BufferData.size()                         &&
         (*CurCh == '\t' || *CurCh == ' ' || *CurCh == '\r' ||
          *CurCh == '\n')) {
    CurPos++;
    CurCh         = Data+CurPos;
  }
  
  if (CurPos >= BufferData.size())
    return 0;                   // EOF

  if (*CurCh == '+') {
    CurPos++;
    return PLUS;
  } else if (*CurCh == '-') {
    CurPos++;
    return MINUS;
  } else if (*CurCh == '*') {
    CurPos++;
    return ASTERISK;
  } else if (*CurCh == '/') {
    CurPos++;
    return SLASH;
  } else if (*CurCh == '$') {
    CurPos++;
    return DOLLAR;
  } else if (*CurCh == '@') {
    CurPos++;
    return AT;
  } else if (IsAlpha(*CurCh)) {
    const char *Start  = CurCh;
    size_t      Length = 0;
    
    do {
      Length++;
      CurPos++;
      CurCh = Data+CurPos;

    } while (CurPos < BufferData.size() && (IsAlphaOrDigit(*CurCh) || *CurCh == '_'));

    StringRef *Str = new StringRef(Start, Length);

    // Check for keywords
    if (Str->compare("double")   == 0) {
      return DOUBLE;
    } else if (Str->compare("field")    == 0) {
      return FIELD;
    } else if (Str->compare("float")    == 0) {
      return FLOAT;
    } else if (Str->compare("grid")     == 0) {
      return GRID;
    } else if (Str->compare("in")       == 0) {
      return IN;
    } else if (Str->compare("inout")    == 0) {
      return INOUT;
    } else if (Str->compare("is")       == 0) {
      return IS;
    } else if (Str->compare("let")      == 0) {
      return LET;
    } else if (Str->compare("out")      == 0) {
      return OUT;
    } else if (Str->compare("param")    == 0) {
      return PARAM;
    } else if (Str->compare("program")  == 0) {
      return PROGRAM;
    }

    // Not a keyword
    InternedStrings.push_back(Str);
    Value->Ident        = Str;
    return IDENT;
  } else if (IsDigit(*CurCh)) {
    const char *Start   = CurCh;
    size_t      Length  = 0;
    bool        IsFloat = false;
      
    do {
      if (*CurCh == '.') IsFloat = true;
      
      Length++;
      CurPos++;
      CurCh = Data+CurPos;
      
    } while (CurPos < BufferData.size() && (IsDigit(*CurCh) || *CurCh == '.'));

    if (CurPos < BufferData.size() && (*CurCh == 'e' || *CurCh == 'E')) {
      // Start of an exponent

      IsFloat = true;
      
      CurPos++;
      CurCh = Data+CurPos;
      Length++;
      
      if (CurPos == BufferData.size() || (!IsDigit(*CurCh) && *CurCh != '-')) {
        SrcMgr.PrintMessage(SMLoc::getFromPointer(Data+CurPos),
                            SourceMgr::DK_Error, "Missing exponent");
        return 0;
      }

      if (*CurCh == '-') {
        Length++;
        CurPos++;
        CurCh = Data+CurPos;

        if (CurPos == BufferData.size() || !IsDigit(*CurCh)) {
          SrcMgr.PrintMessage(SMLoc::getFromPointer(Data+CurPos),
                              SourceMgr::DK_Error, "Missing exponent");
          return 0;
        }
      }

      do {
        Length++;
        CurPos++;
        CurCh = Data+CurPos;
      
      } while (CurPos < BufferData.size() && IsDigit(*CurCh));

    }
    
    StringRef Str = StringRef(Start, Length);

    if (IsFloat) {
      APFloat DoubleValue = APFloat(APFloat::IEEEdouble, Str);
      Value->DoubleConst  = DoubleValue.convertToDouble();
      return DOUBLECONST;
    } else {
      long    IntValue    = atol(Str.data());
      Value->IntConst     = IntValue;
      return INTCONST;
    }
  } else if (*CurCh == '=') {
    CurPos++;
    return EQUALS;
  } else if (*CurCh == '(') {
    CurPos++;
    return OPENPARENS;
  } else if (*CurCh == ')') {
    CurPos++;
    return CLOSEPARENS;
  } else if (*CurCh == '[') {
    CurPos++;
    return OPENBRACE;
  } else if (*CurCh == ']') {
    CurPos++;
    return CLOSEBRACE;
  } else if (*CurCh == ',') {
    CurPos++;
    return COMMA;
  } else if (*CurCh == ':') {
    CurPos++;
    return COLON;
  }

  CurPos++;
  // If we get here, then we have no idea how to lex this!
  printError("Unknown symbol");
  
  return 0;
}
コード例 #12
0
ファイル: llvm-profdata.cpp プロジェクト: ralic/llvm
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);
}
コード例 #13
0
void swift::ide::printSubmoduleInterface(
       Module *M,
       ArrayRef<StringRef> FullModuleName,
       Optional<StringRef> GroupName,
       ModuleTraversalOptions TraversalOptions,
       ASTPrinter &Printer,
       const PrintOptions &Options,
       const bool PrintSynthesizedExtensions) {
  auto AdjustedOptions = Options;
  adjustPrintOptions(AdjustedOptions);

  SmallVector<Decl *, 1> Decls;
  M->getDisplayDecls(Decls);

  auto &SwiftContext = M->getASTContext();
  auto &Importer =
      static_cast<ClangImporter &>(*SwiftContext.getClangModuleLoader());

  const clang::Module *InterestingClangModule = nullptr;

  SmallVector<ImportDecl *, 1> ImportDecls;
  llvm::DenseSet<const clang::Module *> ClangModulesForImports;
  SmallVector<Decl *, 1> SwiftDecls;
  llvm::DenseMap<const clang::Module *,
                 SmallVector<std::pair<Decl *, clang::SourceLocation>, 1>>
    ClangDecls;

  // Drop top-level module name.
  FullModuleName = FullModuleName.slice(1);

  InterestingClangModule = M->findUnderlyingClangModule();
  if (InterestingClangModule) {
    for (StringRef Name : FullModuleName) {
      InterestingClangModule = InterestingClangModule->findSubmodule(Name);
      if (!InterestingClangModule)
        return;
    }
  } else {
    assert(FullModuleName.empty());
  }

  // If we're printing recursively, find all of the submodules to print.
  if (InterestingClangModule) {
    if (TraversalOptions) {
      SmallVector<const clang::Module *, 8> Worklist;
      SmallPtrSet<const clang::Module *, 8> Visited;
      Worklist.push_back(InterestingClangModule);
      Visited.insert(InterestingClangModule);
      while (!Worklist.empty()) {
        const clang::Module *CM = Worklist.pop_back_val();
        if (!(TraversalOptions & ModuleTraversal::VisitHidden) &&
            CM->IsExplicit)
          continue;

        ClangDecls.insert({ CM, {} });

        // If we're supposed to visit submodules, add them now.
        if (TraversalOptions & ModuleTraversal::VisitSubmodules) {
          for (auto Sub = CM->submodule_begin(), SubEnd = CM->submodule_end();
               Sub != SubEnd; ++Sub) {
            if (Visited.insert(*Sub).second)
              Worklist.push_back(*Sub);
          }
        }
      }
    } else {
      ClangDecls.insert({ InterestingClangModule, {} });
    }
  }

  // Collect those submodules that are actually imported but have no import decls
  // in the module.
  llvm::SmallPtrSet<const clang::Module *, 16> NoImportSubModules;
  if (InterestingClangModule) {
    // Assume all submodules are missing.
    for (auto It =InterestingClangModule->submodule_begin();
         It != InterestingClangModule->submodule_end(); It ++) {
      NoImportSubModules.insert(*It);
    }
  }

  // Separate the declarations that we are going to print into different
  // buckets.
  for (Decl *D : Decls) {

    // Skip declarations that are not accessible.
    if (auto *VD = dyn_cast<ValueDecl>(D)) {
      if (Options.AccessibilityFilter > Accessibility::Private &&
          VD->hasAccessibility() &&
          VD->getFormalAccess() < Options.AccessibilityFilter)
        continue;
    }

    auto ShouldPrintImport = [&](ImportDecl *ImportD) -> bool {
      if (!InterestingClangModule)
        return true;
      auto ClangMod = ImportD->getClangModule();
      if (!ClangMod)
        return true;
      if (!ClangMod->isSubModule())
        return true;
      if (ClangMod == InterestingClangModule)
        return false;
      // FIXME: const-ness on the clang API.
      return ClangMod->isSubModuleOf(
                          const_cast<clang::Module*>(InterestingClangModule));
    };

    if (auto ID = dyn_cast<ImportDecl>(D)) {
      if (ShouldPrintImport(ID)) {
        if (ID->getClangModule())
          // Erase those submodules that are not missing.
          NoImportSubModules.erase(ID->getClangModule());
        if (ID->getImportKind() == ImportKind::Module) {
          // Make sure we don't print duplicate imports, due to getting imports
          // for both a clang module and its overlay.
          if (auto *ClangMod = getUnderlyingClangModuleForImport(ID)) {
            auto P = ClangModulesForImports.insert(ClangMod);
            bool IsNew = P.second;
            if (!IsNew)
              continue;
          }
        }
        ImportDecls.push_back(ID);
      }
      continue;
    }

    auto addToClangDecls = [&](Decl *D) {
      assert(D->hasClangNode());
      auto CN = D->getClangNode();
      clang::SourceLocation Loc = CN.getLocation();

      auto *OwningModule = Importer.getClangOwningModule(CN);
      auto I = ClangDecls.find(OwningModule);
      if (I != ClangDecls.end()) {
        I->second.push_back({ D, Loc });
      }
    };

    if (D->hasClangNode()) {
      addToClangDecls(D);
      continue;
    }
    if (FullModuleName.empty()) {
      // If group name is given and the decl does not belong to the group, skip it.
      if (GroupName && (!D->getGroupName() ||
                        D->getGroupName().getValue() != GroupName.getValue()))
        continue;
      // Add Swift decls if we are printing the top-level module.
      SwiftDecls.push_back(D);
    }
  }

  // Create the missing import decls and add to the collector.
  for (auto *SM : NoImportSubModules) {
    ImportDecls.push_back(createImportDecl(M->getASTContext(), M, SM, {}));
  }

  auto &ClangSourceManager = Importer.getClangASTContext().getSourceManager();

  // Sort imported declarations in source order *within a submodule*.
  for (auto &P : ClangDecls) {
    std::sort(P.second.begin(), P.second.end(),
              [&](std::pair<Decl *, clang::SourceLocation> LHS,
                  std::pair<Decl *, clang::SourceLocation> RHS) -> bool {
                return ClangSourceManager.isBeforeInTranslationUnit(LHS.second,
                                                                    RHS.second);
              });
  }

  // Sort Swift declarations so that we print them in a consistent order.
  std::sort(ImportDecls.begin(), ImportDecls.end(),
            [](ImportDecl *LHS, ImportDecl *RHS) -> bool {
    auto LHSPath = LHS->getFullAccessPath();
    auto RHSPath = RHS->getFullAccessPath();
    for (unsigned i = 0, e = std::min(LHSPath.size(), RHSPath.size()); i != e;
         i++) {
      if (int Ret = LHSPath[i].first.str().compare(RHSPath[i].first.str()))
        return Ret < 0;
    }
    return false;
  });

  // If the group name is specified, we sort them according to their source order,
  // which is the order preserved by getTopLeveDecls.
  if (!GroupName) {
    std::sort(SwiftDecls.begin(), SwiftDecls.end(),
      [&](Decl *LHS, Decl *RHS) -> bool {
        auto *LHSValue = dyn_cast<ValueDecl>(LHS);
        auto *RHSValue = dyn_cast<ValueDecl>(RHS);

        if (LHSValue && RHSValue) {
          StringRef LHSName = LHSValue->getName().str();
          StringRef RHSName = RHSValue->getName().str();
          if (int Ret = LHSName.compare(RHSName))
            return Ret < 0;
          // FIXME: this is not sufficient to establish a total order for overloaded
          // decls.
          return LHS->getKind() < RHS->getKind();
        }

        return LHS->getKind() < RHS->getKind();
      });
  }

  ASTPrinter *PrinterToUse = &Printer;

  ClangCommentPrinter RegularCommentPrinter(Printer, Importer);
  if (Options.PrintRegularClangComments)
    PrinterToUse = &RegularCommentPrinter;

  auto PrintDecl = [&](Decl *D) -> bool {
    ASTPrinter &Printer = *PrinterToUse;
    if (!shouldPrint(D, AdjustedOptions)) {
      Printer.avoidPrintDeclPost(D);
      return false;
    }
    if (auto Ext = dyn_cast<ExtensionDecl>(D)) {
      // Clang extensions (categories) are always printed in source order.
      // Swift extensions are printed with their associated type unless it's
      // a cross-module extension.
      if (!Ext->hasClangNode()) {
        auto ExtendedNominal = Ext->getExtendedType()->getAnyNominal();
        if (Ext->getModuleContext() == ExtendedNominal->getModuleContext())
          return false;
      }
    }

    if (D->print(Printer, AdjustedOptions)) {
      Printer << "\n";
      if (auto NTD = dyn_cast<NominalTypeDecl>(D)) {
        std::queue<NominalTypeDecl *> SubDecls{{NTD}};

        while (!SubDecls.empty()) {
          auto NTD = SubDecls.front();
          SubDecls.pop();

          // Add sub-types of NTD.
          for (auto Sub : NTD->getMembers())
            if (auto N = dyn_cast<NominalTypeDecl>(Sub))
              SubDecls.push(N);

          // Print Ext and add sub-types of Ext.
          for (auto Ext : NTD->getExtensions()) {
            if (!shouldPrint(Ext, AdjustedOptions)) {
              Printer.avoidPrintDeclPost(Ext);
              continue;
            }
            if (Ext->hasClangNode())
              continue; // will be printed in its source location, see above.
            Printer << "\n";
            Ext->print(Printer, AdjustedOptions);
            Printer << "\n";
            for (auto Sub : Ext->getMembers())
              if (auto N = dyn_cast<NominalTypeDecl>(Sub))
                SubDecls.push(N);
          }
          if (!PrintSynthesizedExtensions)
            continue;

          // Print synthesized extensions.
          llvm::SmallPtrSet<ExtensionDecl *, 10> ExtensionsFromConformances;
          findExtensionsFromConformingProtocols(D, ExtensionsFromConformances);
          AdjustedOptions.initArchetypeTransformerForSynthesizedExtensions(NTD);
          for (auto ET : ExtensionsFromConformances) {
            if (!shouldPrint(ET, AdjustedOptions))
              continue;
            Printer << "\n";
            Printer << "/// Synthesized extension from ";
            ET->getExtendedTypeLoc().getType().print(Printer, AdjustedOptions);
            Printer << "\n";
            ET->print(Printer, AdjustedOptions);
            Printer << "\n";
          }
          AdjustedOptions.clearArchetypeTransformerForSynthesizedExtensions();
        }
      }
      return true;
    }
    return false;
  };

  // Imports from the stdlib are internal details that don't need to be exposed.
  if (!M->isStdlibModule()) {
    for (auto *D : ImportDecls)
      PrintDecl(D);
    Printer << "\n";
  }

  {
    using ModuleAndName = std::pair<const clang::Module *, std::string>;
    SmallVector<ModuleAndName, 8> ClangModules;
    for (auto P : ClangDecls) {
      ClangModules.push_back({ P.first, P.first->getFullModuleName() });
    }
    // Sort modules by name.
    std::sort(ClangModules.begin(), ClangModules.end(),
              [](const ModuleAndName &LHS, const ModuleAndName &RHS)
                -> bool {
                  return LHS.second < RHS.second;
              });

    for (auto CM : ClangModules) {
      for (auto DeclAndLoc : ClangDecls[CM.first])
        PrintDecl(DeclAndLoc.first);
    }
  }

  if (!(TraversalOptions & ModuleTraversal::SkipOverlay) ||
      !InterestingClangModule) {
    for (auto *D : SwiftDecls) {
      if (PrintDecl(D))
        Printer << "\n";
    }
  }
}
コード例 #14
0
ファイル: LLILCJit.cpp プロジェクト: haibo031031/llilc
void ObjectLoadListener::recordRelocations(
    const ObjectFile &Obj, const RuntimeDyld::LoadedObjectInfo &L) {
  for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end();
       SI != SE; ++SI) {
    section_iterator Section = SI->getRelocatedSection();

    if (Section == SE) {
      continue;
    }

    StringRef SectionName;
    std::error_code ErrorCode = Section->getName(SectionName);
    if (ErrorCode) {
      assert(false && ErrorCode.message().c_str());
    }

    if (SectionName.startswith(".debug") ||
        SectionName.startswith(".rela.debug") ||
        !SectionName.compare(".pdata") || SectionName.startswith(".eh_frame") ||
        SectionName.startswith(".rela.eh_frame")) {
      // Skip sections whose contents are not directly reported to the EE
      continue;
    }

    relocation_iterator I = SI->relocation_begin();
    relocation_iterator E = SI->relocation_end();

    for (; I != E; ++I) {
      symbol_iterator Symbol = I->getSymbol();
      assert(Symbol != Obj.symbol_end());
      ErrorOr<section_iterator> SymbolSectionOrErr = Symbol->getSection();
      assert(!SymbolSectionOrErr.getError());
      object::section_iterator SymbolSection = *SymbolSectionOrErr;
      const bool IsExtern = SymbolSection == Obj.section_end();
      uint64_t RelType = I->getType();
      uint64_t Offset = I->getOffset();
      uint8_t *RelocationTarget = nullptr;
      if (IsExtern) {
        // This is an external symbol. Verify that it's one we created for
        // a global variable and report the relocation via Jit interface.
        ErrorOr<StringRef> NameOrError = Symbol->getName();
        assert(NameOrError);
        StringRef TargetName = NameOrError.get();
        assert(Context->NameToHandleMap.count(TargetName) == 1);
        RelocationTarget = (uint8_t *)Context->NameToHandleMap[TargetName];
      } else {
        RelocationTarget = (uint8_t *)(L.getSectionLoadAddress(*SymbolSection) +
                                       Symbol->getValue());
      }

      uint64_t Addend = 0;
      uint64_t EERelType = getRelocationType(RelType);
      uint64_t SectionAddress = L.getSectionLoadAddress(*Section);
      assert(SectionAddress != 0);
      uint8_t *FixupAddress = (uint8_t *)(SectionAddress + Offset);

      if (Obj.isELF()) {
        // Addend is part of the relocation
        ELFRelocationRef ElfReloc(*I);
        ErrorOr<uint64_t> ElfAddend = ElfReloc.getAddend();
        assert(!ElfAddend.getError());
        Addend = ElfAddend.get();
      } else {
        // Addend is read from the location to be fixed up
        Addend = getRelocationAddend(RelType, FixupAddress);
      }

      Context->JitInfo->recordRelocation(FixupAddress,
                                         RelocationTarget + Addend, EERelType);
    }
  }
}
コード例 #15
0
ファイル: string_ref.hpp プロジェクト: kh156/cpp-driver
 inline bool ends_with(const StringRef& input, const StringRef& target) {
   return input.length() >= target.length() &&
       input.compare(input.length() - target.length(), target.length(), target) == 0;
 }