void StackmapJITEventListener::NotifyObjectEmitted(const llvm::object::ObjectFile& Obj, const llvm::RuntimeDyld::LoadedObjectInfo& L) { // llvm::outs() << "An object has been emitted:\n"; llvm_error_code code; for (const auto& sec : Obj.sections()) { llvm::StringRef name; code = sec.getName(name); assert(!code); if (name == ".llvm_stackmaps") { assert(stackmap_address == 0); stackmap_address = L.getSectionLoadAddress(name); assert(stackmap_address > 0); } } }
virtual void NotifyObjectEmitted(const llvm::object::ObjectFile& Obj, const llvm::RuntimeDyld::LoadedObjectInfo& L) { static StatCounter code_bytes("code_bytes"); code_bytes.log(Obj.getData().size()); llvm_error_code code; for (const auto& sym : Obj.symbols()) { llvm::object::section_iterator section(Obj.section_end()); code = sym.getSection(section); assert(!code); bool is_text; #if LLVMREV < 219314 code = section->isText(is_text); assert(!code); #else is_text = section->isText(); #endif if (!is_text) continue; llvm::StringRef name; code = sym.getName(name); assert(!code); uint64_t size; code = sym.getSize(size); assert(!code); if (name == ".text") continue; uint64_t sym_addr = L.getSymbolLoadAddress(name); assert(sym_addr); g.func_addr_registry.registerFunction(name.data(), (void*)sym_addr, size, NULL); } }
virtual void NotifyObjectEmitted(const llvm::object::ObjectFile& Obj, const llvm::RuntimeDyld::LoadedObjectInfo& L) { std::unique_ptr<llvm::DIContext> Context(llvm::DIContext::getDWARFContext(Obj)); assert(g.cur_cf); uint64_t func_addr = 0; // remains 0 until we find a function // Search through the symbols to find the function that got JIT'ed. // (We only JIT one function at a time.) for (const auto& sym : Obj.symbols()) { llvm::object::SymbolRef::Type SymType; if (sym.getType(SymType) || SymType != llvm::object::SymbolRef::ST_Function) continue; llvm::StringRef Name; uint64_t Size; if (sym.getName(Name) || sym.getSize(Size)) continue; // Found a function! assert(!func_addr); func_addr = L.getSymbolLoadAddress(Name); assert(func_addr); // TODO this should be the Python name, not the C name: #if LLVMREV < 208921 llvm::DILineInfoTable lines = Context->getLineInfoForAddressRange( func_addr, Size, llvm::DILineInfoSpecifier::FunctionName | llvm::DILineInfoSpecifier::FileLineInfo | llvm::DILineInfoSpecifier::AbsoluteFilePath); #else llvm::DILineInfoTable lines = Context->getLineInfoForAddressRange( func_addr, Size, llvm::DILineInfoSpecifier(llvm::DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, llvm::DILineInfoSpecifier::FunctionNameKind::LinkageName)); #endif if (VERBOSITY() >= 3) { for (int i = 0; i < lines.size(); i++) { printf("%s:%d, %s: %lx\n", lines[i].second.FileName.c_str(), lines[i].second.Line, lines[i].second.FunctionName.c_str(), lines[i].first); } } assert(g.cur_cf->code_start == 0); g.cur_cf->code_start = func_addr; g.cur_cf->code_size = Size; cf_registry.registerCF(g.cur_cf); } assert(func_addr); // Libunwind support: bool found_text = false, found_eh_frame = false; uint64_t text_addr = -1, text_size = -1; uint64_t eh_frame_addr = -1, eh_frame_size = -1; for (const auto& sec : Obj.sections()) { llvm::StringRef name; llvm_error_code code = sec.getName(name); assert(!code); uint64_t addr, size; if (name == ".eh_frame") { assert(!found_eh_frame); eh_frame_addr = L.getSectionLoadAddress(name); eh_frame_size = sec.getSize(); if (VERBOSITY() >= 2) printf("eh_frame: %lx %lx\n", eh_frame_addr, eh_frame_size); found_eh_frame = true; } else if (name == ".text") { assert(!found_text); text_addr = L.getSectionLoadAddress(name); text_size = sec.getSize(); if (VERBOSITY() >= 2) printf("text: %lx %lx\n", text_addr, text_size); found_text = true; } } assert(found_text); assert(found_eh_frame); assert(text_addr == func_addr); registerDynamicEhFrame(text_addr, text_size, eh_frame_addr, eh_frame_size); }