+static int printLineInfoForInput() {
+ // 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 = new TrivialMemoryManager;
+ RuntimeDyld Dyld(MemMgr);
+
+ // Load the input memory buffer.
+ OwningPtr<MemoryBuffer> InputBuffer;
+ OwningPtr<ObjectImage> LoadedObject;
+ if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFileList[i],
+ InputBuffer))
+ return Error("unable to read input: '" + ec.message() + "'");
+
+ // Load the object file
+ LoadedObject.reset(Dyld.loadObject(new ObjectBuffer(InputBuffer.take())));
+ if (!LoadedObject) {
+ return Error(Dyld.getErrorString());
+ }
+
+ // Resolve all the relocations we can.
+ Dyld.resolveRelocations();
+
+ OwningPtr<DIContext> Context(DIContext::getDWARFContext(LoadedObject->getObjectFile()));
+
+ // Use symbol info to iterate functions in the object.
+ error_code ec;
+ for (object::symbol_iterator I = LoadedObject->begin_symbols(),
+ E = LoadedObject->end_symbols();
+ I != E && !ec;
+ I.increment(ec)) {
+ 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.getFileName()
+ << ", line:" << It->second.getLine() << "\n";
+ }
+ }
+ }
+ }