|
18 | 18 | #include "lldb/Symbol/ObjectFile.h"
|
19 | 19 | #include "lldb/Target/MemoryRegionInfo.h"
|
20 | 20 | #include "lldb/Target/Platform.h"
|
| 21 | +#include "lldb/Target/RegisterContext.h" |
21 | 22 | #include "lldb/Target/Target.h"
|
22 | 23 | #include "lldb/Target/Thread.h"
|
23 | 24 | #include "lldb/Target/ThreadPlanRunToAddress.h"
|
@@ -866,3 +867,82 @@ bool DynamicLoaderPOSIXDYLD::AlwaysRelyOnEHUnwindInfo(
|
866 | 867 | bool DynamicLoaderPOSIXDYLD::IsCoreFile() const {
|
867 | 868 | return !m_process->IsLiveDebugSession();
|
868 | 869 | }
|
| 870 | + |
| 871 | +// For our ELF/POSIX builds save off the fs_base/gs_base regions |
| 872 | +static void AddThreadLocalMemoryRegions(Process &process, ThreadSP &thread_sp, |
| 873 | + std::vector<MemoryRegionInfo> &ranges) { |
| 874 | + lldb::RegisterContextSP reg_ctx = thread_sp->GetRegisterContext(); |
| 875 | + if (!reg_ctx) |
| 876 | + return; |
| 877 | + |
| 878 | + const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo( |
| 879 | + lldb::RegisterKind::eRegisterKindGeneric, LLDB_REGNUM_GENERIC_TP); |
| 880 | + if (!reg_info) |
| 881 | + return; |
| 882 | + |
| 883 | + lldb_private::RegisterValue thread_local_register_value; |
| 884 | + bool success = reg_ctx->ReadRegister(reg_info, thread_local_register_value); |
| 885 | + if (!success) |
| 886 | + return; |
| 887 | + |
| 888 | + const uint64_t fail_value = UINT64_MAX; |
| 889 | + bool readSuccess = false; |
| 890 | + const lldb::addr_t reg_value_addr = |
| 891 | + thread_local_register_value.GetAsUInt64(fail_value, &readSuccess); |
| 892 | + if (!readSuccess || reg_value_addr == fail_value) |
| 893 | + return; |
| 894 | + |
| 895 | + MemoryRegionInfo thread_local_region; |
| 896 | + Status err = process.GetMemoryRegionInfo(reg_value_addr, thread_local_region); |
| 897 | + if (err.Fail()) |
| 898 | + return; |
| 899 | + |
| 900 | + ranges.push_back(thread_local_region); |
| 901 | +} |
| 902 | + |
| 903 | +// Save off the link map for core files. |
| 904 | +static void AddLinkMapSections(Process &process, |
| 905 | + std::vector<MemoryRegionInfo> &ranges) { |
| 906 | + ModuleList &module_list = process.GetTarget().GetImages(); |
| 907 | + Target *target = &process.GetTarget(); |
| 908 | + for (size_t idx = 0; idx < module_list.GetSize(); idx++) { |
| 909 | + ModuleSP module_sp = module_list.GetModuleAtIndex(idx); |
| 910 | + if (!module_sp) |
| 911 | + continue; |
| 912 | + |
| 913 | + ObjectFile *obj = module_sp->GetObjectFile(); |
| 914 | + if (!obj) |
| 915 | + continue; |
| 916 | + Address addr = obj->GetImageInfoAddress(target); |
| 917 | + addr_t load_addr = addr.GetLoadAddress(target); |
| 918 | + if (load_addr == LLDB_INVALID_ADDRESS) |
| 919 | + continue; |
| 920 | + |
| 921 | + MemoryRegionInfo link_map_section; |
| 922 | + Status err = process.GetMemoryRegionInfo(load_addr, link_map_section); |
| 923 | + if (err.Fail()) |
| 924 | + continue; |
| 925 | + |
| 926 | + ranges.push_back(link_map_section); |
| 927 | + } |
| 928 | +} |
| 929 | + |
| 930 | +void DynamicLoaderPOSIXDYLD::CalculateDynamicSaveCoreRanges( |
| 931 | + lldb_private::Process &process, |
| 932 | + std::vector<lldb_private::MemoryRegionInfo> &ranges, |
| 933 | + llvm::function_ref<bool(const lldb_private::Thread &)> |
| 934 | + save_thread_predicate) { |
| 935 | + ThreadList &thread_list = process.GetThreadList(); |
| 936 | + for (size_t idx = 0; idx < thread_list.GetSize(); idx++) { |
| 937 | + ThreadSP thread_sp = thread_list.GetThreadAtIndex(idx); |
| 938 | + if (!thread_sp) |
| 939 | + continue; |
| 940 | + |
| 941 | + if (!save_thread_predicate(*thread_sp)) |
| 942 | + continue; |
| 943 | + |
| 944 | + AddThreadLocalMemoryRegions(process, thread_sp, ranges); |
| 945 | + } |
| 946 | + |
| 947 | + AddLinkMapSections(process, ranges); |
| 948 | +} |
0 commit comments