已合并
[feature]根据断点位置自动下发软硬断点 #130
wiyr0创建于 5月8日
[feature]根据断点位置自动下发软硬断点 #130
已合并
共 13 个文件变更+163-8
| @@ -426,9 +426,15 @@ public: | |||
| 426 | /// | 426 | /// |
| 427 | /// \param[in] range | 427 | /// \param[in] range |
| 428 | /// The section offset based address for this function. | 428 | /// The section offset based address for this function. |
| 429 | + | ||
| 429 | Function(CompileUnit *comp_unit, lldb::user_id_t func_uid, | 430 | Function(CompileUnit *comp_unit, lldb::user_id_t func_uid, |
| 430 | lldb::user_id_t func_type_uid, const Mangled &mangled, | 431 | lldb::user_id_t func_type_uid, const Mangled &mangled, |
| 431 | Type *func_type, const AddressRange &range); | 432 | Type *func_type, const AddressRange &range); |
| 433 | + | ||
| 434 | + Function(CompileUnit *comp_unit, lldb::user_id_t func_uid, | ||
| 435 | + lldb::user_id_t func_type_uid, const Mangled &mangled, | ||
| 436 | + Type *func_type, const AddressRange &range, uint32_t function_class = 0); | ||
| 437 | + | ||
| 432 | 438 | ||
| 433 | /// Destructor. | 439 | /// Destructor. |
| 434 | ~Function() override; | 440 | ~Function() override; |
| @@ -446,6 +452,11 @@ public: | |||
| 446 | 452 | ||
| 447 | const AddressRange &GetAddressRange() { return m_range; } | 453 | const AddressRange &GetAddressRange() { return m_range; } |
| 448 | 454 | ||
| 455 | + | ||
| 456 | + uint32_t GetFunctionClass() const { return m_function_class; } | ||
| 457 | + void SetFunctionClass(uint32_t function_class) { m_function_class = function_class; } | ||
| 458 | + | ||
| 459 | + | ||
| 449 | lldb::LanguageType GetLanguage() const; | 460 | lldb::LanguageType GetLanguage() const; |
| 450 | /// Find the file and line number of the source location of the start of the | 461 | /// Find the file and line number of the source location of the start of the |
| 451 | /// function. This will use the declaration if present and fall back on the | 462 | /// function. This will use the declaration if present and fall back on the |
| @@ -672,6 +683,10 @@ protected: | |||
| 672 | /// Outgoing call edges. | 683 | /// Outgoing call edges. |
| 673 | std::vector<std::unique_ptr<CallEdge>> m_call_edges; | 684 | std::vector<std::unique_ptr<CallEdge>> m_call_edges; |
| 674 | 685 | ||
| 686 | + | ||
| 687 | + uint32_t m_function_class; | ||
| 688 | + | ||
| 689 | + | ||
| 675 | private: | 690 | private: |
| 676 | Function(const Function &) = delete; | 691 | Function(const Function &) = delete; |
| 677 | const Function &operator=(const Function &) = delete; | 692 | const Function &operator=(const Function &) = delete; |
| @@ -1530,6 +1530,14 @@ public: | |||
| 1530 | /// Print all the signals set in this target. | 1530 | /// Print all the signals set in this target. |
| 1531 | void PrintDummySignals(Stream &strm, Args &signals); | 1531 | void PrintDummySignals(Stream &strm, Args &signals); |
| 1532 | 1532 | ||
| 1533 | + | ||
| 1534 | + void UpdateBreakpoints(const lldb::ModuleSP &old_module_sp, | ||
| 1535 | + const lldb::ModuleSP &new_module_sp) { | ||
| 1536 | + ModuleList module_list; | ||
| 1537 | + return NotifyModuleUpdated(module_list, old_module_sp, new_module_sp); | ||
| 1538 | + } | ||
| 1539 | + | ||
| 1540 | + | ||
| 1533 | protected: | 1541 | protected: |
| 1534 | /// Implementing of ModuleList::Notifier. | 1542 | /// Implementing of ModuleList::Notifier. |
| 1535 | 1543 | ||
| @@ -58,6 +58,20 @@ enum class AddressClass { | |||
| 58 | }; | 58 | }; |
| 59 | 59 | ||
| 60 | 60 | ||
| 61 | +enum class DeviceFunctionClass { | ||
| 62 | + NONE = 0U, | ||
| 63 | + HOST = 1U << 0, | ||
| 64 | + KERNEL = 1U << 1, | ||
| 65 | + AICORE = 1U << 2, | ||
| 66 | + AICPU = 1U << 3, | ||
| 67 | + AICUBE = 1U << 4, | ||
| 68 | + AIVEC = 1U << 5, | ||
| 69 | + SIMT_ENTRY = 1U << 6, // simt vector function | ||
| 70 | + SIMT_CALLEE = 1U << 7, // function called by simt vector function | ||
| 71 | + SIMD_ENTRY = 1U << 8, // simd vector function | ||
| 72 | + SIMD_CALLEE = 1U << 9 // function called by simd vector function | ||
| 73 | +}; | ||
| 74 | + | ||
| 61 | enum class DeviceAddressClass { | 75 | enum class DeviceAddressClass { |
| 62 | NONE = 0U, | 76 | NONE = 0U, |
| 63 | GM = 1U << 0, | 77 | GM = 1U << 0, |
| @@ -250,6 +250,20 @@ bool Breakpoint::IsInternal() const { return LLDB_BREAK_ID_IS_INTERNAL(m_bid); } | |||
| 250 | 250 | ||
| 251 | BreakpointLocationSP Breakpoint::AddLocation(const Address &addr, | 251 | BreakpointLocationSP Breakpoint::AddLocation(const Address &addr, |
| 252 | bool *new_location) { | 252 | bool *new_location) { |
| 253 | + | ||
| 254 | + Log *log = GetLog(LLDBLog::Breakpoints); | ||
| 255 | + const auto *function = addr.CalculateSymbolContextFunction(); | ||
| 256 | + LLDB_LOG(log, "Detect function_calss={0:x}", function->GetFunctionClass()); | ||
| 257 | + if (function && (function->GetFunctionClass() & | ||
| 258 | + (static_cast<uint32_t>(DeviceFunctionClass::SIMD_CALLEE) | | ||
| 259 | + static_cast<uint32_t>(DeviceFunctionClass::SIMT_CALLEE) | | ||
| 260 | + static_cast<uint32_t>(DeviceFunctionClass::SIMT_ENTRY) | | ||
| 261 | + static_cast<uint32_t>(DeviceFunctionClass::SIMT_ENTRY)))) { | ||
| 262 | + m_hardware = true; | ||
| 263 | + LLDB_LOG(log, "Simt/Simd function only support hardware breakpoint, auto " | ||
| 264 | + "change breakpoint type to hardware"); | ||
| 265 | + } | ||
| 266 | + | ||
| 253 | return m_locations.AddLocation(addr, m_resolve_indirect_symbols, | 267 | return m_locations.AddLocation(addr, m_resolve_indirect_symbols, |
| 254 | new_location); | 268 | new_location); |
| 255 | } | 269 | } |
| @@ -491,11 +491,14 @@ void DynamicLoaderPOSIXDYLD::RefreshDeviceModules() { | |||
| 491 | // remove this module from loaded modules if any one of these conditions below are met: | 491 | // remove this module from loaded modules if any one of these conditions below are met: |
| 492 | // 1. it is a hiipu64-module and we need to reset all device binary. | 492 | // 1. it is a hiipu64-module and we need to reset all device binary. |
| 493 | // 2. it is a duplicate module. we replace the old one with it in loaded modules. | 493 | // 2. it is a duplicate module. we replace the old one with it in loaded modules. |
| 494 | - if ((reset_all_device_binary && | 494 | + if (reset_all_device_binary && |
| 495 | - module_sp->GetArchitecture().GetTriple().getArch() == llvm::Triple::hiipu64) || | 495 | + module_sp->GetArchitecture().GetTriple().getArch() == |
| 496 | - (!reset_all_device_binary && | 496 | + llvm::Triple::hiipu64) { |
| 497 | - module_sp && module_sp->GetUUID() == device_module->GetUUID())) { | ||
| 498 | old_modules.Append(module_sp); | 497 | old_modules.Append(module_sp); |
| 498 | + } else if (!reset_all_device_binary && module_sp && | ||
| 499 | + module_sp->GetUUID() == device_module->GetUUID()) { | ||
| 500 | + old_modules.Append(module_sp); | ||
| 501 | + m_process->GetTarget().UpdateBreakpoints(module_sp, device_module); | ||
| 499 | } | 502 | } |
| 500 | } | 503 | } |
| 501 | 504 | ||
| @@ -504,7 +507,7 @@ void DynamicLoaderPOSIXDYLD::RefreshDeviceModules() { | |||
| 504 | UnloadSections(module_sp); | 507 | UnloadSections(module_sp); |
| 505 | } | 508 | } |
| 506 | loaded_modules.Remove(old_modules); | 509 | loaded_modules.Remove(old_modules); |
| 507 | - m_process->GetTarget().ModulesDidUnload(old_modules, false); | 510 | + m_process->GetTarget().ModulesDidUnload(old_modules, true); |
| 508 | 511 | ||
| 509 | // added new modules | 512 | // added new modules |
| 510 | new_modules.Append(device_module); | 513 | new_modules.Append(device_module); |
| @@ -558,9 +561,10 @@ void DynamicLoaderPOSIXDYLD::AddRendezvousVFCallBreakpoint(ModuleSP device_modul | |||
| 558 | uint64_t break_addr = par.first; | 561 | uint64_t break_addr = par.first; |
| 559 | auto dyld_break = target.CreateBreakpoint(break_addr + base_pc + smallest_instr_bytes, true, false); | 562 | auto dyld_break = target.CreateBreakpoint(break_addr + base_pc + smallest_instr_bytes, true, false); |
| 560 | if (dyld_break->GetNumResolvedLocations() != 1) { | 563 | if (dyld_break->GetNumResolvedLocations() != 1) { |
| 561 | - LLDB_LOG(log, "Rendezvoud vf_call breakpoint has abnormal number of" | 564 | + LLDB_LOG(log, |
| 565 | + "Rendezvoud vf_call breakpoint has abnormal number of" | ||
| 562 | " resolved locations {0}. It's supposed to be exactly 1", | 566 | " resolved locations {0}. It's supposed to be exactly 1", |
| 563 | - dyld_break->GetNumResolvedLocations()); | 567 | + dyld_break->GetNumResolvedLocations()); |
| 564 | target.RemoveBreakpointByID(dyld_break->GetID()); | 568 | target.RemoveBreakpointByID(dyld_break->GetID()); |
| 565 | continue; | 569 | continue; |
| 566 | } | 570 | } |
| @@ -2402,9 +2402,16 @@ DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit, | |||
| 2402 | if (tag != DW_TAG_subprogram) | 2402 | if (tag != DW_TAG_subprogram) |
| 2403 | return nullptr; | 2403 | return nullptr; |
| 2404 | 2404 | ||
| 2405 | + | ||
| 2405 | if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line, | 2406 | if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line, |
| 2406 | decl_column, call_file, call_line, call_column, | 2407 | decl_column, call_file, call_line, call_column, |
| 2407 | &frame_base)) { | 2408 | &frame_base)) { |
| 2409 | + | ||
| 2410 | + std::optional<int> function_class; | ||
| 2411 | + if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line, | ||
| 2412 | + decl_column, call_file, call_line, call_column, | ||
| 2413 | + function_class, &frame_base)) { | ||
| 2414 | + | ||
| 2408 | Mangled func_name; | 2415 | Mangled func_name; |
| 2409 | if (mangled) | 2416 | if (mangled) |
| 2410 | func_name.SetValue(ConstString(mangled)); | 2417 | func_name.SetValue(ConstString(mangled)); |
| @@ -2436,11 +2443,19 @@ DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit, | |||
| 2436 | assert(func_type == nullptr || func_type != DIE_IS_BEING_PARSED); | 2443 | assert(func_type == nullptr || func_type != DIE_IS_BEING_PARSED); |
| 2437 | 2444 | ||
| 2438 | const user_id_t func_user_id = die.GetID(); | 2445 | const user_id_t func_user_id = die.GetID(); |
| 2446 | + | ||
| 2439 | func_sp = | 2447 | func_sp = |
| 2440 | std::make_shared<Function>(&comp_unit, | 2448 | std::make_shared<Function>(&comp_unit, |
| 2441 | func_user_id, // UserID is the DIE offset | 2449 | func_user_id, // UserID is the DIE offset |
| 2442 | func_user_id, func_name, func_type, | 2450 | func_user_id, func_name, func_type, |
| 2443 | func_range); // first address range | 2451 | func_range); // first address range |
| 2452 | + | ||
| 2453 | + func_sp = | ||
| 2454 | + std::make_shared<Function>(&comp_unit, | ||
| 2455 | + func_user_id, // UserID is the DIE offset | ||
| 2456 | + func_user_id, func_name, func_type, | ||
| 2457 | + func_range, function_class ? function_class.value() : 0); // first address range | ||
| 2458 | + | ||
| 2444 | 2459 | ||
| 2445 | if (func_sp.get() != nullptr) { | 2460 | if (func_sp.get() != nullptr) { |
| 2446 | if (frame_base.IsValid()) | 2461 | if (frame_base.IsValid()) |
| @@ -574,6 +574,7 @@ bool DWARFDIE::IsMethod() const { | |||
| 574 | return false; | 574 | return false; |
| 575 | } | 575 | } |
| 576 | 576 | ||
| 577 | + | ||
| 577 | bool DWARFDIE::GetDIENamesAndRanges( | 578 | bool DWARFDIE::GetDIENamesAndRanges( |
| 578 | const char *&name, const char *&mangled, DWARFRangeList &ranges, | 579 | const char *&name, const char *&mangled, DWARFRangeList &ranges, |
| 579 | std::optional<int> &decl_file, std::optional<int> &decl_line, | 580 | std::optional<int> &decl_file, std::optional<int> &decl_line, |
| @@ -587,6 +588,22 @@ bool DWARFDIE::GetDIENamesAndRanges( | |||
| 587 | } else | 588 | } else |
| 588 | return false; | 589 | return false; |
| 589 | } | 590 | } |
| 591 | + | ||
| 592 | +bool DWARFDIE::GetDIENamesAndRanges( | ||
| 593 | + const char *&name, const char *&mangled, DWARFRangeList &ranges, | ||
| 594 | + std::optional<int> &decl_file, std::optional<int> &decl_line, | ||
| 595 | + std::optional<int> &decl_column, std::optional<int> &call_file, | ||
| 596 | + std::optional<int> &call_line, std::optional<int> &call_column, | ||
| 597 | + std::optional<int> &function_class, | ||
| 598 | + lldb_private::DWARFExpressionList *frame_base) const { | ||
| 599 | + if (IsValid()) { | ||
| 600 | + return m_die->GetDIENamesAndRanges( | ||
| 601 | + GetCU(), name, mangled, ranges, decl_file, decl_line, decl_column, | ||
| 602 | + call_file, call_line, call_column, function_class, frame_base); | ||
| 603 | + } else | ||
| 604 | + return false; | ||
| 605 | +} | ||
| 606 | + | ||
| 590 | 607 | ||
| 591 | llvm::iterator_range<DWARFDIE::child_iterator> DWARFDIE::children() const { | 608 | llvm::iterator_range<DWARFDIE::child_iterator> DWARFDIE::children() const { |
| 592 | return llvm::make_range(child_iterator(*this), child_iterator()); | 609 | return llvm::make_range(child_iterator(*this), child_iterator()); |
| @@ -96,12 +96,21 @@ public: | |||
| 96 | DWARFDIE | 96 | DWARFDIE |
| 97 | GetAttributeValueAsReferenceDIE(const dw_attr_t attr) const; | 97 | GetAttributeValueAsReferenceDIE(const dw_attr_t attr) const; |
| 98 | 98 | ||
| 99 | + | ||
| 99 | bool GetDIENamesAndRanges( | 100 | bool GetDIENamesAndRanges( |
| 100 | const char *&name, const char *&mangled, DWARFRangeList &ranges, | 101 | const char *&name, const char *&mangled, DWARFRangeList &ranges, |
| 101 | std::optional<int> &decl_file, std::optional<int> &decl_line, | 102 | std::optional<int> &decl_file, std::optional<int> &decl_line, |
| 102 | std::optional<int> &decl_column, std::optional<int> &call_file, | 103 | std::optional<int> &decl_column, std::optional<int> &call_file, |
| 103 | std::optional<int> &call_line, std::optional<int> &call_column, | 104 | std::optional<int> &call_line, std::optional<int> &call_column, |
| 104 | DWARFExpressionList *frame_base) const; | 105 | DWARFExpressionList *frame_base) const; |
| 106 | + | ||
| 107 | + bool GetDIENamesAndRanges( | ||
| 108 | + const char *&name, const char *&mangled, DWARFRangeList &ranges, | ||
| 109 | + std::optional<int> &decl_file, std::optional<int> &decl_line, | ||
| 110 | + std::optional<int> &decl_column, std::optional<int> &call_file, | ||
| 111 | + std::optional<int> &call_line, std::optional<int> &call_column, | ||
| 112 | + std::optional<int> &function_class, DWARFExpressionList *frame_base) const; | ||
| 113 | + | ||
| 105 | 114 | ||
| 106 | /// The range of all the children of this DIE. | 115 | /// The range of all the children of this DIE. |
| 107 | llvm::iterator_range<child_iterator> children() const; | 116 | llvm::iterator_range<child_iterator> children() const; |
| @@ -116,12 +116,21 @@ static void ExtractAttrAndFormValue( | |||
| 116 | // | 116 | // |
| 117 | // Gets the valid address ranges for a given DIE by looking for a | 117 | // Gets the valid address ranges for a given DIE by looking for a |
| 118 | // DW_AT_low_pc/DW_AT_high_pc pair, DW_AT_entry_pc, or DW_AT_ranges attributes. | 118 | // DW_AT_low_pc/DW_AT_high_pc pair, DW_AT_entry_pc, or DW_AT_ranges attributes. |
| 119 | + | ||
| 119 | bool DWARFDebugInfoEntry::GetDIENamesAndRanges( | 120 | bool DWARFDebugInfoEntry::GetDIENamesAndRanges( |
| 120 | DWARFUnit *cu, const char *&name, const char *&mangled, | 121 | DWARFUnit *cu, const char *&name, const char *&mangled, |
| 121 | DWARFRangeList &ranges, std::optional<int> &decl_file, | 122 | DWARFRangeList &ranges, std::optional<int> &decl_file, |
| 122 | std::optional<int> &decl_line, std::optional<int> &decl_column, | 123 | std::optional<int> &decl_line, std::optional<int> &decl_column, |
| 123 | std::optional<int> &call_file, std::optional<int> &call_line, | 124 | std::optional<int> &call_file, std::optional<int> &call_line, |
| 124 | std::optional<int> &call_column, DWARFExpressionList *frame_base) const { | 125 | std::optional<int> &call_column, DWARFExpressionList *frame_base) const { |
| 126 | + | ||
| 127 | +bool DWARFDebugInfoEntry::GetDIENamesAndRanges( | ||
| 128 | + DWARFUnit *cu, const char *&name, const char *&mangled, | ||
| 129 | + DWARFRangeList &ranges, std::optional<int> &decl_file, | ||
| 130 | + std::optional<int> &decl_line, std::optional<int> &decl_column, | ||
| 131 | + std::optional<int> &call_file, std::optional<int> &call_line, | ||
| 132 | + std::optional<int> &call_column, std::optional<int> &function_class, DWARFExpressionList *frame_base) const { | ||
| 133 | + | ||
| 125 | dw_addr_t lo_pc = LLDB_INVALID_ADDRESS; | 134 | dw_addr_t lo_pc = LLDB_INVALID_ADDRESS; |
| 126 | dw_addr_t hi_pc = LLDB_INVALID_ADDRESS; | 135 | dw_addr_t hi_pc = LLDB_INVALID_ADDRESS; |
| 127 | std::vector<DWARFDIE> dies; | 136 | std::vector<DWARFDIE> dies; |
| @@ -252,6 +261,12 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges( | |||
| 252 | } | 261 | } |
| 253 | } | 262 | } |
| 254 | break; | 263 | break; |
| 264 | + | ||
| 265 | + case DW_AT_function_class: | ||
| 266 | + if (!function_class) { | ||
| 267 | + function_class = form_value.Unsigned(); | ||
| 268 | + } | ||
| 269 | + | ||
| 255 | 270 | ||
| 256 | default: | 271 | default: |
| 257 | break; | 272 | break; |
| @@ -278,9 +293,16 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges( | |||
| 278 | if (ranges.IsEmpty() || name == nullptr || mangled == nullptr) { | 293 | if (ranges.IsEmpty() || name == nullptr || mangled == nullptr) { |
| 279 | for (const DWARFDIE &die : dies) { | 294 | for (const DWARFDIE &die : dies) { |
| 280 | if (die) { | 295 | if (die) { |
| 296 | + | ||
| 281 | die.GetDIE()->GetDIENamesAndRanges(die.GetCU(), name, mangled, ranges, | 297 | die.GetDIE()->GetDIENamesAndRanges(die.GetCU(), name, mangled, ranges, |
| 282 | decl_file, decl_line, decl_column, | 298 | decl_file, decl_line, decl_column, |
| 283 | call_file, call_line, call_column); | 299 | call_file, call_line, call_column); |
| 300 | + | ||
| 301 | + std::optional<int> function_class; | ||
| 302 | + die.GetDIE()->GetDIENamesAndRanges(die.GetCU(), name, mangled, ranges, | ||
| 303 | + decl_file, decl_line, decl_column, | ||
| 304 | + call_file, call_line, call_column, function_class); | ||
| 305 | + | ||
| 284 | } | 306 | } |
| 285 | } | 307 | } |
| 286 | } | 308 | } |
| @@ -106,6 +106,7 @@ public: | |||
| 106 | 106 | ||
| 107 | const char *GetPubname(const DWARFUnit *cu) const; | 107 | const char *GetPubname(const DWARFUnit *cu) const; |
| 108 | 108 | ||
| 109 | + | ||
| 109 | bool GetDIENamesAndRanges(DWARFUnit *cu, const char *&name, | 110 | bool GetDIENamesAndRanges(DWARFUnit *cu, const char *&name, |
| 110 | const char *&mangled, DWARFRangeList &rangeList, | 111 | const char *&mangled, DWARFRangeList &rangeList, |
| 111 | std::optional<int> &decl_file, | 112 | std::optional<int> &decl_file, |
| @@ -115,6 +116,18 @@ public: | |||
| 115 | std::optional<int> &call_line, | 116 | std::optional<int> &call_line, |
| 116 | std::optional<int> &call_column, | 117 | std::optional<int> &call_column, |
| 117 | DWARFExpressionList *frame_base = nullptr) const; | 118 | DWARFExpressionList *frame_base = nullptr) const; |
| 119 | + | ||
| 120 | + bool GetDIENamesAndRanges(DWARFUnit *cu, const char *&name, | ||
| 121 | + const char *&mangled, DWARFRangeList &rangeList, | ||
| 122 | + std::optional<int> &decl_file, | ||
| 123 | + std::optional<int> &decl_line, | ||
| 124 | + std::optional<int> &decl_column, | ||
| 125 | + std::optional<int> &call_file, | ||
| 126 | + std::optional<int> &call_line, | ||
| 127 | + std::optional<int> &call_column, | ||
| 128 | + std::optional<int> &function_class, | ||
| 129 | + DWARFExpressionList *frame_base = nullptr) const; | ||
| 130 | + | ||
| 118 | 131 | ||
| 119 | const llvm::DWARFAbbreviationDeclaration * | 132 | const llvm::DWARFAbbreviationDeclaration * |
| 120 | GetAbbreviationDeclarationPtr(const DWARFUnit *cu) const; | 133 | GetAbbreviationDeclarationPtr(const DWARFUnit *cu) const; |
| @@ -1368,9 +1368,17 @@ size_t SymbolFileDWARF::ParseBlocksRecursive( | |||
| 1368 | std::optional<int> call_file; | 1368 | std::optional<int> call_file; |
| 1369 | std::optional<int> call_line; | 1369 | std::optional<int> call_line; |
| 1370 | std::optional<int> call_column; | 1370 | std::optional<int> call_column; |
| 1371 | + | ||
| 1372 | + | ||
| 1371 | if (die.GetDIENamesAndRanges(name, mangled_name, ranges, decl_file, | 1373 | if (die.GetDIENamesAndRanges(name, mangled_name, ranges, decl_file, |
| 1372 | decl_line, decl_column, call_file, call_line, | 1374 | decl_line, decl_column, call_file, call_line, |
| 1373 | call_column, nullptr)) { | 1375 | call_column, nullptr)) { |
| 1376 | + | ||
| 1377 | + std::optional<int> function_class; | ||
| 1378 | + if (die.GetDIENamesAndRanges(name, mangled_name, ranges, decl_file, | ||
| 1379 | + decl_line, decl_column, call_file, call_line, | ||
| 1380 | + call_column, function_class, nullptr)) { | ||
| 1381 | + | ||
| 1374 | if (tag == DW_TAG_subprogram) { | 1382 | if (tag == DW_TAG_subprogram) { |
| 1375 | assert(subprogram_low_pc == LLDB_INVALID_ADDRESS); | 1383 | assert(subprogram_low_pc == LLDB_INVALID_ADDRESS); |
| 1376 | subprogram_low_pc = ranges.GetMinRangeBase(0); | 1384 | subprogram_low_pc = ranges.GetMinRangeBase(0); |
| @@ -1773,7 +1781,7 @@ SymbolFileDWARF *SymbolFileDWARF::GetDIERefSymbolFile(const DIERef &die_ref) { | |||
| 1773 | // We have a SymbolFileDWARFDebugMap, so let it find the right file | 1781 | // We have a SymbolFileDWARFDebugMap, so let it find the right file |
| 1774 | if (SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile()) | 1782 | if (SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile()) |
| 1775 | return debug_map->GetSymbolFileByOSOIndex(*file_index); | 1783 | return debug_map->GetSymbolFileByOSOIndex(*file_index); |
| 1776 | - | 1784 | + |
| 1777 | // Handle the .dwp file case correctly | 1785 | // Handle the .dwp file case correctly |
| 1778 | if (*file_index == DIERef::k_file_index_mask) | 1786 | if (*file_index == DIERef::k_file_index_mask) |
| 1779 | return GetDwpSymbolFile().get(); // DWP case | 1787 | return GetDwpSymbolFile().get(); // DWP case |
| @@ -255,6 +255,7 @@ Function *IndirectCallEdge::GetCallee(ModuleList &images, | |||
| 255 | /// @} | 255 | /// @} |
| 256 | 256 | ||
| 257 | // | 257 | // |
| 258 | + | ||
| 258 | Function::Function(CompileUnit *comp_unit, lldb::user_id_t func_uid, | 259 | Function::Function(CompileUnit *comp_unit, lldb::user_id_t func_uid, |
| 259 | lldb::user_id_t type_uid, const Mangled &mangled, Type *type, | 260 | lldb::user_id_t type_uid, const Mangled &mangled, Type *type, |
| 260 | const AddressRange &range) | 261 | const AddressRange &range) |
| @@ -265,6 +266,18 @@ Function::Function(CompileUnit *comp_unit, lldb::user_id_t func_uid, | |||
| 265 | assert(comp_unit != nullptr); | 266 | assert(comp_unit != nullptr); |
| 266 | } | 267 | } |
| 267 | 268 | ||
| 269 | + | ||
| 270 | +Function::Function(CompileUnit *comp_unit, lldb::user_id_t func_uid, | ||
| 271 | + lldb::user_id_t type_uid, const Mangled &mangled, Type *type, | ||
| 272 | + const AddressRange &range, uint32_t function_class) | ||
| 273 | + : UserID(func_uid), m_comp_unit(comp_unit), m_type_uid(type_uid), | ||
| 274 | + m_type(type), m_mangled(mangled), m_block(func_uid), m_range(range), | ||
| 275 | + m_frame_base(), m_flags(), m_prologue_byte_size(0), m_function_class(function_class) { | ||
| 276 | + m_block.SetParentScope(this); | ||
| 277 | + assert(comp_unit != nullptr); | ||
| 278 | +} | ||
| 279 | + | ||
| 280 | + | ||
| 268 | Function::~Function() = default; | 281 | Function::~Function() = default; |
| 269 | 282 | ||
| 270 | void Function::GetStartLineSourceInfo(FileSpec &source_file, | 283 | void Function::GetStartLineSourceInfo(FileSpec &source_file, |
| @@ -410,6 +410,9 @@ HANDLE_DW_AT(0x89, export_symbols, 5, DWARF) | |||
| 410 | HANDLE_DW_AT(0x8a, deleted, 5, DWARF) | 410 | HANDLE_DW_AT(0x8a, deleted, 5, DWARF) |
| 411 | HANDLE_DW_AT(0x8b, defaulted, 5, DWARF) | 411 | HANDLE_DW_AT(0x8b, defaulted, 5, DWARF) |
| 412 | HANDLE_DW_AT(0x8c, loclists_base, 5, DWARF) | 412 | HANDLE_DW_AT(0x8c, loclists_base, 5, DWARF) |
| 413 | +// MS_DEBUGGER | ||
| 414 | +HANDLE_DW_AT(0x8d, function_class, 5, DWARF) | ||
| 415 | +// MS_DEBUGGER | ||
| 413 | 416 | ||
| 414 | // Vendor extensions: | 417 | // Vendor extensions: |
| 415 | HANDLE_DW_AT(0x806, GHS_namespace_alias, 0, GHS) | 418 | HANDLE_DW_AT(0x806, GHS_namespace_alias, 0, GHS) |