int main(int argc, char **argv) { // Print a stack trace if we signal out. sys::PrintStackTraceOnErrorSignal(argv[0]); PrettyStackTraceProgram X(argc, argv); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. cl::ParseCommandLineOptions(argc, argv, "llvm dwarf dumper\n"); // Defaults to a.out if no filenames specified. if (InputFilenames.size() == 0) InputFilenames.push_back("a.out"); // Expand any .dSYM bundles to the individual object files contained therein. std::vector<std::string> Objects; for (const auto &F : InputFilenames) { auto Objs = expandBundle(F); Objects.insert(Objects.end(), Objs.begin(), Objs.end()); } std::for_each(Objects.begin(), Objects.end(), DumpInput); return EXIT_SUCCESS; }
int main(int argc, char **argv) { // Print a stack trace if we signal out. sys::PrintStackTraceOnErrorSignal(); PrettyStackTraceProgram X(argc, argv); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. cl::ParseCommandLineOptions(argc, argv, "llvm object size dumper\n"); ToolName = argv[0]; if (OutputFormatShort.getNumOccurrences()) OutputFormat = OutputFormatShort; if (RadixShort.getNumOccurrences()) Radix = RadixShort; for (unsigned i = 0; i < ArchFlags.size(); ++i) { if (ArchFlags[i] == "all") { ArchAll = true; } else { Triple T = MachOObjectFile::getArch(ArchFlags[i]); if (T.getArch() == Triple::UnknownArch) { outs() << ToolName << ": for the -arch option: Unknown architecture " << "named '" << ArchFlags[i] << "'"; return 1; } } } if (InputFilenames.size() == 0) InputFilenames.push_back("a.out"); moreThanOneFile = InputFilenames.size() > 1; std::for_each(InputFilenames.begin(), InputFilenames.end(), PrintFileSectionSizes); return 0; }
// Load and link the objects specified on the command line, but do not execute // anything. Instead, attach a RuntimeDyldChecker instance and call it to // verify the correctness of the linked memory. static int linkAndVerify() { // Check for missing triple. if (TripleName == "") { llvm::errs() << "Error: -triple required when running in -verify mode.\n"; return 1; } // Look up the target and build the disassembler. Triple TheTriple(Triple::normalize(TripleName)); std::string ErrorStr; const Target *TheTarget = TargetRegistry::lookupTarget("", TheTriple, ErrorStr); if (!TheTarget) { llvm::errs() << "Error accessing target '" << TripleName << "': " << ErrorStr << "\n"; return 1; } TripleName = TheTriple.getTriple(); std::unique_ptr<MCSubtargetInfo> STI( TheTarget->createMCSubtargetInfo(TripleName, "", "")); assert(STI && "Unable to create subtarget info!"); std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName)); assert(MRI && "Unable to create target register info!"); std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, TripleName)); assert(MAI && "Unable to create target asm info!"); MCContext Ctx(MAI.get(), MRI.get(), nullptr); std::unique_ptr<MCDisassembler> Disassembler( TheTarget->createMCDisassembler(*STI, Ctx)); assert(Disassembler && "Unable to create disassembler!"); std::unique_ptr<MCInstrInfo> MII(TheTarget->createMCInstrInfo()); std::unique_ptr<MCInstPrinter> InstPrinter( TheTarget->createMCInstPrinter(0, *MAI, *MII, *MRI, *STI)); // Load any dylibs requested on the command line. loadDylibs(); // Instantiate a dynamic linker. TrivialMemoryManager MemMgr; RuntimeDyld Dyld(&MemMgr); RuntimeDyldChecker Checker(Dyld, Disassembler.get(), InstPrinter.get(), llvm::dbgs()); // If we don't have any input files, read from stdin. if (!InputFileList.size()) InputFileList.push_back("-"); for(unsigned i = 0, e = InputFileList.size(); i != e; ++i) { // Load the input memory buffer. ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer = MemoryBuffer::getFileOrSTDIN(InputFileList[i]); if (std::error_code EC = InputBuffer.getError()) return Error("unable to read input: '" + EC.message() + "'"); std::unique_ptr<ObjectImage> LoadedObject; // Load the object file LoadedObject.reset( Dyld.loadObject(new ObjectBuffer(InputBuffer.get().release()))); if (!LoadedObject) { return Error(Dyld.getErrorString()); } } // Re-map the section addresses into the phony target address space. remapSections(TheTriple, MemMgr, Dyld); // Resolve all the relocations we can. Dyld.resolveRelocations(); int ErrorCode = checkAllExpressions(Checker); if (Dyld.hasError()) { errs() << "RTDyld reported an error applying relocations:\n " << Dyld.getErrorString() << "\n"; ErrorCode = 1; } return ErrorCode; }
static int printLineInfoForInput() { // Load any dylibs requested on the command line. loadDylibs(); // If we don't have any input files, read from stdin. if (!InputFileList.size()) InputFileList.push_back("-"); for(unsigned i = 0, e = InputFileList.size(); i != e; ++i) { // Instantiate a dynamic linker. TrivialMemoryManager MemMgr; RuntimeDyld Dyld(&MemMgr); // Load the input memory buffer. ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer = MemoryBuffer::getFileOrSTDIN(InputFileList[i]); if (std::error_code EC = InputBuffer.getError()) return Error("unable to read input: '" + EC.message() + "'"); std::unique_ptr<ObjectImage> LoadedObject; // Load the object file LoadedObject.reset( Dyld.loadObject(new ObjectBuffer(InputBuffer.get().release()))); if (!LoadedObject) { return Error(Dyld.getErrorString()); } // Resolve all the relocations we can. Dyld.resolveRelocations(); std::unique_ptr<DIContext> Context( DIContext::getDWARFContext(*LoadedObject->getObjectFile())); // Use symbol info to iterate functions in the object. for (object::symbol_iterator I = LoadedObject->begin_symbols(), E = LoadedObject->end_symbols(); I != E; ++I) { object::SymbolRef::Type SymType; if (I->getType(SymType)) continue; if (SymType == object::SymbolRef::ST_Function) { StringRef Name; uint64_t Addr; uint64_t Size; if (I->getName(Name)) continue; if (I->getAddress(Addr)) continue; if (I->getSize(Size)) continue; outs() << "Function: " << Name << ", Size = " << Size << "\n"; DILineInfoTable Lines = Context->getLineInfoForAddressRange(Addr, Size); DILineInfoTable::iterator Begin = Lines.begin(); DILineInfoTable::iterator End = Lines.end(); for (DILineInfoTable::iterator It = Begin; It != End; ++It) { outs() << " Line info @ " << It->first - Addr << ": " << It->second.FileName << ", line:" << It->second.Line << "\n"; } } } } return 0; }
// Load and link the objects specified on the command line, but do not execute // anything. Instead, attach a RuntimeDyldChecker instance and call it to // verify the correctness of the linked memory. static int linkAndVerify() { // Check for missing triple. if (TripleName == "") ErrorAndExit("-triple required when running in -verify mode."); // Look up the target and build the disassembler. Triple TheTriple(Triple::normalize(TripleName)); std::string ErrorStr; const Target *TheTarget = TargetRegistry::lookupTarget("", TheTriple, ErrorStr); if (!TheTarget) ErrorAndExit("Error accessing target '" + TripleName + "': " + ErrorStr); TripleName = TheTriple.getTriple(); std::unique_ptr<MCSubtargetInfo> STI( TheTarget->createMCSubtargetInfo(TripleName, MCPU, "")); if (!STI) ErrorAndExit("Unable to create subtarget info!"); std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName)); if (!MRI) ErrorAndExit("Unable to create target register info!"); std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, TripleName)); if (!MAI) ErrorAndExit("Unable to create target asm info!"); MCContext Ctx(MAI.get(), MRI.get(), nullptr); std::unique_ptr<MCDisassembler> Disassembler( TheTarget->createMCDisassembler(*STI, Ctx)); if (!Disassembler) ErrorAndExit("Unable to create disassembler!"); std::unique_ptr<MCInstrInfo> MII(TheTarget->createMCInstrInfo()); std::unique_ptr<MCInstPrinter> InstPrinter( TheTarget->createMCInstPrinter(Triple(TripleName), 0, *MAI, *MII, *MRI)); // Load any dylibs requested on the command line. loadDylibs(); // Instantiate a dynamic linker. TrivialMemoryManager MemMgr; doPreallocation(MemMgr); RuntimeDyld Dyld(MemMgr, MemMgr); Dyld.setProcessAllSections(true); RuntimeDyldChecker Checker(Dyld, Disassembler.get(), InstPrinter.get(), llvm::dbgs()); // If we don't have any input files, read from stdin. if (!InputFileList.size()) InputFileList.push_back("-"); for (auto &Filename : InputFileList) { // Load the input memory buffer. ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer = MemoryBuffer::getFileOrSTDIN(Filename); if (std::error_code EC = InputBuffer.getError()) ErrorAndExit("unable to read input: '" + EC.message() + "'"); Expected<std::unique_ptr<ObjectFile>> MaybeObj( ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef())); if (!MaybeObj) { std::string Buf; raw_string_ostream OS(Buf); logAllUnhandledErrors(MaybeObj.takeError(), OS, ""); OS.flush(); ErrorAndExit("unable to create object file: '" + Buf + "'"); } ObjectFile &Obj = **MaybeObj; // Load the object file Dyld.loadObject(Obj); if (Dyld.hasError()) { ErrorAndExit(Dyld.getErrorString()); } } // Re-map the section addresses into the phony target address space and add // dummy symbols. remapSectionsAndSymbols(TheTriple, MemMgr, Checker); // Resolve all the relocations we can. Dyld.resolveRelocations(); // Register EH frames. Dyld.registerEHFrames(); int ErrorCode = checkAllExpressions(Checker); if (Dyld.hasError()) ErrorAndExit("RTDyld reported an error applying relocations:\n " + Dyld.getErrorString()); return ErrorCode; }
static int executeInput() { // Load any dylibs requested on the command line. loadDylibs(); // Instantiate a dynamic linker. TrivialMemoryManager MemMgr; doPreallocation(MemMgr); RuntimeDyld Dyld(MemMgr, MemMgr); // If we don't have any input files, read from stdin. if (!InputFileList.size()) InputFileList.push_back("-"); for (auto &File : InputFileList) { // Load the input memory buffer. ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer = MemoryBuffer::getFileOrSTDIN(File); if (std::error_code EC = InputBuffer.getError()) ErrorAndExit("unable to read input: '" + EC.message() + "'"); Expected<std::unique_ptr<ObjectFile>> MaybeObj( ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef())); if (!MaybeObj) { std::string Buf; raw_string_ostream OS(Buf); logAllUnhandledErrors(MaybeObj.takeError(), OS, ""); OS.flush(); ErrorAndExit("unable to create object file: '" + Buf + "'"); } ObjectFile &Obj = **MaybeObj; // Load the object file Dyld.loadObject(Obj); if (Dyld.hasError()) { ErrorAndExit(Dyld.getErrorString()); } } // Resove all the relocations we can. // FIXME: Error out if there are unresolved relocations. Dyld.resolveRelocations(); // Get the address of the entry point (_main by default). void *MainAddress = Dyld.getSymbolLocalAddress(EntryPoint); if (!MainAddress) ErrorAndExit("no definition for '" + EntryPoint + "'"); // Invalidate the instruction cache for each loaded function. for (auto &FM : MemMgr.FunctionMemory) { // Make sure the memory is executable. // setExecutable will call InvalidateInstructionCache. std::string ErrorStr; if (!sys::Memory::setExecutable(FM, &ErrorStr)) ErrorAndExit("unable to mark function executable: '" + ErrorStr + "'"); } // Dispatch to _main(). errs() << "loaded '" << EntryPoint << "' at: " << (void*)MainAddress << "\n"; int (*Main)(int, const char**) = (int(*)(int,const char**)) uintptr_t(MainAddress); const char **Argv = new const char*[2]; // Use the name of the first input object module as argv[0] for the target. Argv[0] = InputFileList[0].c_str(); Argv[1] = nullptr; return Main(1, Argv); }
static int printLineInfoForInput(bool LoadObjects, bool UseDebugObj) { assert(LoadObjects || !UseDebugObj); // Load any dylibs requested on the command line. loadDylibs(); // If we don't have any input files, read from stdin. if (!InputFileList.size()) InputFileList.push_back("-"); for (auto &File : InputFileList) { // Instantiate a dynamic linker. TrivialMemoryManager MemMgr; RuntimeDyld Dyld(MemMgr, MemMgr); // Load the input memory buffer. ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer = MemoryBuffer::getFileOrSTDIN(File); if (std::error_code EC = InputBuffer.getError()) ErrorAndExit("unable to read input: '" + EC.message() + "'"); Expected<std::unique_ptr<ObjectFile>> MaybeObj( ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef())); if (!MaybeObj) { std::string Buf; raw_string_ostream OS(Buf); logAllUnhandledErrors(MaybeObj.takeError(), OS, ""); OS.flush(); ErrorAndExit("unable to create object file: '" + Buf + "'"); } ObjectFile &Obj = **MaybeObj; OwningBinary<ObjectFile> DebugObj; std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo = nullptr; ObjectFile *SymbolObj = &Obj; if (LoadObjects) { // Load the object file LoadedObjInfo = Dyld.loadObject(Obj); if (Dyld.hasError()) ErrorAndExit(Dyld.getErrorString()); // Resolve all the relocations we can. Dyld.resolveRelocations(); if (UseDebugObj) { DebugObj = LoadedObjInfo->getObjectForDebug(Obj); SymbolObj = DebugObj.getBinary(); LoadedObjInfo.reset(); } } std::unique_ptr<DIContext> Context( new DWARFContextInMemory(*SymbolObj,LoadedObjInfo.get())); std::vector<std::pair<SymbolRef, uint64_t>> SymAddr = object::computeSymbolSizes(*SymbolObj); // Use symbol info to iterate functions in the object. for (const auto &P : SymAddr) { object::SymbolRef Sym = P.first; Expected<SymbolRef::Type> TypeOrErr = Sym.getType(); if (!TypeOrErr) { // TODO: Actually report errors helpfully. consumeError(TypeOrErr.takeError()); continue; } SymbolRef::Type Type = *TypeOrErr; if (Type == object::SymbolRef::ST_Function) { Expected<StringRef> Name = Sym.getName(); if (!Name) { // TODO: Actually report errors helpfully. consumeError(Name.takeError()); continue; } Expected<uint64_t> AddrOrErr = Sym.getAddress(); if (!AddrOrErr) { // TODO: Actually report errors helpfully. consumeError(AddrOrErr.takeError()); continue; } uint64_t Addr = *AddrOrErr; uint64_t Size = P.second; // If we're not using the debug object, compute the address of the // symbol in memory (rather than that in the unrelocated object file) // and use that to query the DWARFContext. if (!UseDebugObj && LoadObjects) { auto SecOrErr = Sym.getSection(); if (!SecOrErr) { // TODO: Actually report errors helpfully. consumeError(SecOrErr.takeError()); continue; } object::section_iterator Sec = *SecOrErr; StringRef SecName; Sec->getName(SecName); uint64_t SectionLoadAddress = LoadedObjInfo->getSectionLoadAddress(*Sec); if (SectionLoadAddress != 0) Addr += SectionLoadAddress - Sec->getAddress(); } outs() << "Function: " << *Name << ", Size = " << Size << ", Addr = " << Addr << "\n"; DILineInfoTable Lines = Context->getLineInfoForAddressRange(Addr, Size); for (auto &D : Lines) { outs() << " Line info @ " << D.first - Addr << ": " << D.second.FileName << ", line:" << D.second.Line << "\n"; } } } } return 0; }
// I don't think there's a way to specify an initial value for cl::list, // so if nothing was specified, add the default static void AddCheckPrefixIfNeeded() { if (CheckPrefixes.empty()) CheckPrefixes.push_back("CHECK"); }
// Load and link the objects specified on the command line, but do not execute // anything. Instead, attach a RuntimeDyldChecker instance and call it to // verify the correctness of the linked memory. static int linkAndVerify() { // Check for missing triple. if (TripleName == "") { llvm::errs() << "Error: -triple required when running in -verify mode.\n"; return 1; } // Look up the target and build the disassembler. Triple TheTriple(Triple::normalize(TripleName)); std::string ErrorStr; const Target *TheTarget = TargetRegistry::lookupTarget("", TheTriple, ErrorStr); if (!TheTarget) { llvm::errs() << "Error accessing target '" << TripleName << "': " << ErrorStr << "\n"; return 1; } TripleName = TheTriple.getTriple(); std::unique_ptr<MCSubtargetInfo> STI( TheTarget->createMCSubtargetInfo(TripleName, "", "")); assert(STI && "Unable to create subtarget info!"); std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName)); assert(MRI && "Unable to create target register info!"); std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, TripleName)); assert(MAI && "Unable to create target asm info!"); MCContext Ctx(MAI.get(), MRI.get(), nullptr); std::unique_ptr<MCDisassembler> Disassembler( TheTarget->createMCDisassembler(*STI, Ctx)); assert(Disassembler && "Unable to create disassembler!"); std::unique_ptr<MCInstrInfo> MII(TheTarget->createMCInstrInfo()); std::unique_ptr<MCInstPrinter> InstPrinter( TheTarget->createMCInstPrinter(Triple(TripleName), 0, *MAI, *MII, *MRI)); // Load any dylibs requested on the command line. loadDylibs(); // Instantiate a dynamic linker. TrivialMemoryManager MemMgr; RuntimeDyld Dyld(MemMgr, MemMgr); Dyld.setProcessAllSections(true); RuntimeDyldChecker Checker(Dyld, Disassembler.get(), InstPrinter.get(), llvm::dbgs()); // FIXME: Preserve buffers until resolveRelocations time to work around a bug // in RuntimeDyldELF. // This fixme should be fixed ASAP. This is a very brittle workaround. std::vector<std::unique_ptr<MemoryBuffer>> InputBuffers; // If we don't have any input files, read from stdin. if (!InputFileList.size()) InputFileList.push_back("-"); for(unsigned i = 0, e = InputFileList.size(); i != e; ++i) { // Load the input memory buffer. ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer = MemoryBuffer::getFileOrSTDIN(InputFileList[i]); if (std::error_code EC = InputBuffer.getError()) return Error("unable to read input: '" + EC.message() + "'"); ErrorOr<std::unique_ptr<ObjectFile>> MaybeObj( ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef())); if (std::error_code EC = MaybeObj.getError()) return Error("unable to create object file: '" + EC.message() + "'"); ObjectFile &Obj = **MaybeObj; InputBuffers.push_back(std::move(*InputBuffer)); // Load the object file Dyld.loadObject(Obj); if (Dyld.hasError()) { return Error(Dyld.getErrorString()); } } // Re-map the section addresses into the phony target address space. remapSections(TheTriple, MemMgr, Checker); // Resolve all the relocations we can. Dyld.resolveRelocations(); // Register EH frames. Dyld.registerEHFrames(); int ErrorCode = checkAllExpressions(Checker); if (Dyld.hasError()) { errs() << "RTDyld reported an error applying relocations:\n " << Dyld.getErrorString() << "\n"; ErrorCode = 1; } return ErrorCode; }
static int executeInput() { // Load any dylibs requested on the command line. loadDylibs(); // Instantiate a dynamic linker. TrivialMemoryManager MemMgr; RuntimeDyld Dyld(MemMgr, MemMgr); // FIXME: Preserve buffers until resolveRelocations time to work around a bug // in RuntimeDyldELF. // This fixme should be fixed ASAP. This is a very brittle workaround. std::vector<std::unique_ptr<MemoryBuffer>> InputBuffers; // If we don't have any input files, read from stdin. if (!InputFileList.size()) InputFileList.push_back("-"); for(unsigned i = 0, e = InputFileList.size(); i != e; ++i) { // Load the input memory buffer. ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer = MemoryBuffer::getFileOrSTDIN(InputFileList[i]); if (std::error_code EC = InputBuffer.getError()) return Error("unable to read input: '" + EC.message() + "'"); ErrorOr<std::unique_ptr<ObjectFile>> MaybeObj( ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef())); if (std::error_code EC = MaybeObj.getError()) return Error("unable to create object file: '" + EC.message() + "'"); ObjectFile &Obj = **MaybeObj; InputBuffers.push_back(std::move(*InputBuffer)); // Load the object file Dyld.loadObject(Obj); if (Dyld.hasError()) { return Error(Dyld.getErrorString()); } } // Resolve all the relocations we can. Dyld.resolveRelocations(); // Clear instruction cache before code will be executed. MemMgr.invalidateInstructionCache(); // FIXME: Error out if there are unresolved relocations. // Get the address of the entry point (_main by default). void *MainAddress = Dyld.getSymbolLocalAddress(EntryPoint); if (!MainAddress) return Error("no definition for '" + EntryPoint + "'"); // Invalidate the instruction cache for each loaded function. for (unsigned i = 0, e = MemMgr.FunctionMemory.size(); i != e; ++i) { sys::MemoryBlock &Data = MemMgr.FunctionMemory[i]; // Make sure the memory is executable. std::string ErrorStr; sys::Memory::InvalidateInstructionCache(Data.base(), Data.size()); if (!sys::Memory::setExecutable(Data, &ErrorStr)) return Error("unable to mark function executable: '" + ErrorStr + "'"); } // Dispatch to _main(). errs() << "loaded '" << EntryPoint << "' at: " << (void*)MainAddress << "\n"; int (*Main)(int, const char**) = (int(*)(int,const char**)) uintptr_t(MainAddress); const char **Argv = new const char*[2]; // Use the name of the first input object module as argv[0] for the target. Argv[0] = InputFileList[0].c_str(); Argv[1] = nullptr; return Main(1, Argv); }
// Returns true on error. static bool format(StringRef FileName) { ErrorOr<std::unique_ptr<MemoryBuffer>> CodeOrErr = MemoryBuffer::getFileOrSTDIN(FileName); if (std::error_code EC = CodeOrErr.getError()) { llvm::errs() << EC.message() << "\n"; return true; } std::unique_ptr<llvm::MemoryBuffer> Code = std::move(CodeOrErr.get()); if (Code->getBufferSize() == 0) return false; // Empty files are formatted correctly. FormatterDocument Doc(std::move(Code)); if (!Offsets.empty() || !Lengths.empty()) { if (Offsets.size() != Lengths.size()) { llvm::errs() << "error: number of offsets not equal to number of lengths.\n"; return true; } for ( unsigned i=0 ; i < Offsets.size() ; i++ ) { unsigned FromLine = Doc.getLineAndColumn(Offsets[i]).first; unsigned ToLine = Doc.getLineAndColumn(Offsets[i] + Lengths[i]).first; if (ToLine == 0) { llvm::errs() << "error: offset + length after end of file\n"; return true; } std::ostringstream s; s << FromLine << ":" << ToLine; LineRanges.push_back(s.str()); } } if (LineRanges.empty()) LineRanges.push_back("1:999999"); std::string Output = Doc.memBuffer().getBuffer(); Replacements Replaces; for ( unsigned Range = 0 ; Range < LineRanges.size() ; Range++ ) { unsigned FromLine, ToLine; if (parseLineRange(LineRanges[Range], FromLine, ToLine)) { llvm::errs() << "error: invalid <start line>:<end line> pair\n"; return true; } if (FromLine > ToLine) { llvm::errs() << "error: start line should be less than end line\n"; return true; } for ( unsigned Line = FromLine ; Line<=ToLine ; Line++ ) { size_t Offset = getOffsetOfLine(Line,Output); ssize_t Length = getOffsetOfLine(Line+1,Output)-1-Offset; if (Length < 0) break; std::string Formatted = Doc.reformat(LineRange(Line,1), FormatOptions).second; if (Formatted.find_first_not_of(" \t\v\f", 0) == StringRef::npos) Formatted = ""; if (Formatted == Output.substr(Offset, Length)) continue; Output.replace(Offset, Length, Formatted); Doc.updateCode(std::move(MemoryBuffer::getMemBuffer(Output))); Replaces.insert(clang::tooling::Replacement(FileName, Offset, Length, Formatted)); } } if (OutputXML) { llvm::outs() << "<?xml version='1.0'?>\n<replacements>\n"; outputReplacementsXML(Replaces); llvm::outs() << "</replacements>\n"; } else { if (Inplace) { if (FileName == "-") { llvm::errs() << "error: cannot use -i when reading from stdin.\n"; return true; } else { std::error_code EC; raw_fd_ostream writer(FileName, EC, llvm::sys::fs::F_None); if (EC) { llvm::errs() << "error: writing " << FileName << ": " << EC.message() << "\n"; return true; } writer << Output; } } else { llvm::outs() << Output; } } return false; }
static int printLineInfoForInput(bool LoadObjects, bool UseDebugObj) { assert(LoadObjects || !UseDebugObj); // Load any dylibs requested on the command line. loadDylibs(); // If we don't have any input files, read from stdin. if (!InputFileList.size()) InputFileList.push_back("-"); for(unsigned i = 0, e = InputFileList.size(); i != e; ++i) { // Instantiate a dynamic linker. TrivialMemoryManager MemMgr; RuntimeDyld Dyld(MemMgr, MemMgr); // Load the input memory buffer. ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer = MemoryBuffer::getFileOrSTDIN(InputFileList[i]); if (std::error_code EC = InputBuffer.getError()) return Error("unable to read input: '" + EC.message() + "'"); ErrorOr<std::unique_ptr<ObjectFile>> MaybeObj( ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef())); if (std::error_code EC = MaybeObj.getError()) return Error("unable to create object file: '" + EC.message() + "'"); ObjectFile &Obj = **MaybeObj; OwningBinary<ObjectFile> DebugObj; std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo = nullptr; ObjectFile *SymbolObj = &Obj; if (LoadObjects) { // Load the object file LoadedObjInfo = Dyld.loadObject(Obj); if (Dyld.hasError()) return Error(Dyld.getErrorString()); // Resolve all the relocations we can. Dyld.resolveRelocations(); if (UseDebugObj) { DebugObj = LoadedObjInfo->getObjectForDebug(Obj); SymbolObj = DebugObj.getBinary(); LoadedObjInfo.reset(); } } std::unique_ptr<DIContext> Context( new DWARFContextInMemory(*SymbolObj,LoadedObjInfo.get())); std::vector<std::pair<SymbolRef, uint64_t>> SymAddr = object::computeSymbolSizes(*SymbolObj); // Use symbol info to iterate functions in the object. for (const auto &P : SymAddr) { object::SymbolRef Sym = P.first; if (Sym.getType() == object::SymbolRef::ST_Function) { ErrorOr<StringRef> Name = Sym.getName(); if (!Name) continue; ErrorOr<uint64_t> AddrOrErr = Sym.getAddress(); if (!AddrOrErr) continue; uint64_t Addr = *AddrOrErr; uint64_t Size = P.second; // If we're not using the debug object, compute the address of the // symbol in memory (rather than that in the unrelocated object file) // and use that to query the DWARFContext. if (!UseDebugObj && LoadObjects) { object::section_iterator Sec(SymbolObj->section_end()); Sym.getSection(Sec); StringRef SecName; Sec->getName(SecName); uint64_t SectionLoadAddress = LoadedObjInfo->getSectionLoadAddress(*Sec); if (SectionLoadAddress != 0) Addr += SectionLoadAddress - Sec->getAddress(); } outs() << "Function: " << *Name << ", Size = " << Size << ", Addr = " << Addr << "\n"; DILineInfoTable Lines = Context->getLineInfoForAddressRange(Addr, Size); DILineInfoTable::iterator Begin = Lines.begin(); DILineInfoTable::iterator End = Lines.end(); for (DILineInfoTable::iterator It = Begin; It != End; ++It) { outs() << " Line info @ " << It->first - Addr << ": " << It->second.FileName << ", line:" << It->second.Line << "\n"; } } } } return 0; }
/// EmitShellScript - Output the wrapper file that invokes the JIT on the LLVM /// bitcode file for the program. static void EmitShellScript(char **argv, Module *M) { if (Verbose) errs() << "Emitting Shell Script\n"; #if defined(_WIN32) // Windows doesn't support #!/bin/sh style shell scripts in .exe files. To // support windows systems, we copy the llvm-stub.exe executable from the // build tree to the destination file. std::string ErrMsg; sys::Path llvmstub = PrependMainExecutablePath("llvm-stub", argv[0], (void *)(intptr_t)&Optimize); if (llvmstub.isEmpty()) PrintAndExit("Could not find llvm-stub.exe executable!", M); if (0 != sys::CopyFile(sys::Path(OutputFilename), llvmstub, &ErrMsg)) PrintAndExit(ErrMsg, M); return; #endif // Output the script to start the program... std::string ErrorInfo; tool_output_file Out2(OutputFilename.c_str(), ErrorInfo); if (!ErrorInfo.empty()) PrintAndExit(ErrorInfo, M); Out2.os() << "#!/bin/sh\n"; // Allow user to setenv LLVMINTERP if lli is not in their PATH. Out2.os() << "lli=${LLVMINTERP-lli}\n"; Out2.os() << "exec $lli \\\n"; // gcc accepts -l<lib> and implicitly searches /lib and /usr/lib. LibPaths.push_back("/lib"); LibPaths.push_back("/usr/lib"); LibPaths.push_back("/usr/X11R6/lib"); // We don't need to link in libc! In fact, /usr/lib/libc.so may not be a // shared object at all! See RH 8: plain text. std::vector<std::string>::iterator libc = std::find(Libraries.begin(), Libraries.end(), "c"); if (libc != Libraries.end()) Libraries.erase(libc); // List all the shared object (native) libraries this executable will need // on the command line, so that we don't have to do this manually! for (std::vector<std::string>::iterator i = Libraries.begin(), e = Libraries.end(); i != e; ++i) { // try explicit -L arguments first: sys::Path FullLibraryPath; for (cl::list<std::string>::const_iterator P = LibPaths.begin(), E = LibPaths.end(); P != E; ++P) { FullLibraryPath = *P; FullLibraryPath.appendComponent("lib" + *i); FullLibraryPath.appendSuffix(sys::Path::GetDLLSuffix()); if (!FullLibraryPath.isEmpty()) { if (!FullLibraryPath.isDynamicLibrary()) { // Not a native shared library; mark as invalid FullLibraryPath = sys::Path(); } else break; } } if (FullLibraryPath.isEmpty()) FullLibraryPath = sys::Path::FindLibrary(*i); if (!FullLibraryPath.isEmpty()) Out2.os() << " -load=" << FullLibraryPath.str() << " \\\n"; } Out2.os() << " " << BitcodeOutputFilename << " ${1+\"$@\"}\n"; Out2.keep(); }