blob: 7315a82507180a41aa0e843b262b426d296bed65 [file] [log] [blame]
Greg Clayton17f3d052011-08-22 22:30:57 +00001//===-- OperatingSystemDarwinKernel.cpp --------------------------------*- C++ -*-===//
Greg Clayton37f962e2011-08-22 02:49:39 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Greg Clayton17f3d052011-08-22 22:30:57 +000010#include "OperatingSystemDarwinKernel.h"
Greg Clayton37f962e2011-08-22 02:49:39 +000011// C Includes
12// C++ Includes
13// Other libraries and framework includes
14#include "llvm/ADT/Triple.h"
15
16#include "lldb/Core/ArchSpec.h"
17#include "lldb/Core/DataBufferHeap.h"
18#include "lldb/Core/Module.h"
19#include "lldb/Core/PluginManager.h"
20#include "lldb/Core/RegisterValue.h"
21#include "lldb/Core/ValueObjectVariable.h"
Sean Callanan3e80cd92011-10-12 02:08:07 +000022#include "lldb/Symbol/ClangNamespaceDecl.h"
Greg Clayton37f962e2011-08-22 02:49:39 +000023#include "lldb/Symbol/ObjectFile.h"
24#include "lldb/Symbol/VariableList.h"
25#include "lldb/Target/Process.h"
26#include "lldb/Target/StopInfo.h"
27#include "lldb/Target/Target.h"
28#include "lldb/Target/ThreadList.h"
29#include "lldb/Target/Thread.h"
30#include "Plugins/Process/Utility/DynamicRegisterInfo.h"
31#include "Plugins/Process/Utility/RegisterContextMemory.h"
32#include "Plugins/Process/Utility/ThreadMemory.h"
33
34using namespace lldb;
35using namespace lldb_private;
36
37static ConstString &
38GetThreadGPRMemberName ()
39{
40 static ConstString g_gpr_member_name("gpr");
41 return g_gpr_member_name;
42}
43
44void
Greg Clayton17f3d052011-08-22 22:30:57 +000045OperatingSystemDarwinKernel::Initialize()
Greg Clayton37f962e2011-08-22 02:49:39 +000046{
47 PluginManager::RegisterPlugin (GetPluginNameStatic(),
48 GetPluginDescriptionStatic(),
49 CreateInstance);
50}
51
52void
Greg Clayton17f3d052011-08-22 22:30:57 +000053OperatingSystemDarwinKernel::Terminate()
Greg Clayton37f962e2011-08-22 02:49:39 +000054{
55 PluginManager::UnregisterPlugin (CreateInstance);
56}
57
58OperatingSystem *
Greg Clayton17f3d052011-08-22 22:30:57 +000059OperatingSystemDarwinKernel::CreateInstance (Process *process, bool force)
Greg Clayton37f962e2011-08-22 02:49:39 +000060{
61#if 0
62 bool create = force;
63 if (!create)
64 {
65 Module* exe_module = process->GetTarget().GetExecutableModulePointer();
66 if (exe_module)
67 {
68 ObjectFile *object_file = exe_module->GetObjectFile();
69 if (object_file)
70 {
Sean Callananac725af2012-02-10 20:22:35 +000071 if (object_file->GetStrata() != ObjectFile::eStrataKernel)
Greg Clayton37f962e2011-08-22 02:49:39 +000072 {
Sean Callananac725af2012-02-10 20:22:35 +000073 return NULL;
Greg Clayton37f962e2011-08-22 02:49:39 +000074 }
75 }
76 }
77
78 // We can limit the creation of this plug-in to "*-apple-darwin" triples
79 // if we command out the lines below...
80// if (create)
81// {
82// const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
83// create = triple_ref.getOS() == llvm::Triple::Darwin && triple_ref.getVendor() == llvm::Triple::Apple;
84// }
85 }
86
87 if (create)
Greg Clayton17f3d052011-08-22 22:30:57 +000088 return new OperatingSystemDarwinKernel (process);
Greg Clayton37f962e2011-08-22 02:49:39 +000089#endif
90 return NULL;
91}
92
93
94const char *
Greg Clayton17f3d052011-08-22 22:30:57 +000095OperatingSystemDarwinKernel::GetPluginNameStatic()
Greg Clayton37f962e2011-08-22 02:49:39 +000096{
97 return "macosx-kernel";
98}
99
100const char *
Greg Clayton17f3d052011-08-22 22:30:57 +0000101OperatingSystemDarwinKernel::GetPluginDescriptionStatic()
Greg Clayton37f962e2011-08-22 02:49:39 +0000102{
103 return "Operating system plug-in that gathers OS information from darwin kernels.";
104}
105
106
Greg Clayton17f3d052011-08-22 22:30:57 +0000107OperatingSystemDarwinKernel::OperatingSystemDarwinKernel (lldb_private::Process *process) :
Greg Clayton37f962e2011-08-22 02:49:39 +0000108 OperatingSystem (process),
109 m_thread_list_valobj_sp (),
110 m_register_info_ap ()
111{
112}
113
Greg Clayton17f3d052011-08-22 22:30:57 +0000114OperatingSystemDarwinKernel::~OperatingSystemDarwinKernel ()
Greg Clayton37f962e2011-08-22 02:49:39 +0000115{
116}
117
118ValueObjectSP
Greg Clayton17f3d052011-08-22 22:30:57 +0000119OperatingSystemDarwinKernel::GetThreadListValueObject ()
Greg Clayton37f962e2011-08-22 02:49:39 +0000120{
121 if (m_thread_list_valobj_sp.get() == NULL)
122 {
123 VariableList variable_list;
124 const uint32_t max_matches = 1;
125 const bool append = true;
126 static ConstString g_thread_list_name("g_thread_list");
127 Module *exe_module = m_process->GetTarget().GetExecutableModulePointer();
128 if (exe_module)
129 {
Sean Callanan3e80cd92011-10-12 02:08:07 +0000130 if (exe_module->FindGlobalVariables (g_thread_list_name,
131 NULL,
Greg Clayton37f962e2011-08-22 02:49:39 +0000132 append,
133 max_matches,
134 variable_list))
135 {
136 m_thread_list_valobj_sp = ValueObjectVariable::Create (m_process, variable_list.GetVariableAtIndex(0));
137 }
138 }
139 }
140 return m_thread_list_valobj_sp;
141}
142
143DynamicRegisterInfo *
Greg Clayton17f3d052011-08-22 22:30:57 +0000144OperatingSystemDarwinKernel::GetDynamicRegisterInfo ()
Greg Clayton37f962e2011-08-22 02:49:39 +0000145{
146 if (m_register_info_ap.get() == NULL && m_thread_list_valobj_sp)
147 {
148 m_register_info_ap.reset (new DynamicRegisterInfo());
149 ConstString empty_name;
150 const bool can_create = true;
151 AddressType addr_type;
152 addr_t base_addr = LLDB_INVALID_ADDRESS;
153 ValueObjectSP gpr_valobj_sp (m_thread_list_valobj_sp->GetChildMemberWithName(GetThreadGPRMemberName (), can_create));
154
155 if (gpr_valobj_sp->IsPointerType ())
Enrico Granata91544802011-09-06 19:20:51 +0000156 base_addr = gpr_valobj_sp->GetPointerValue (&addr_type);
Greg Clayton37f962e2011-08-22 02:49:39 +0000157 else
Enrico Granata91544802011-09-06 19:20:51 +0000158 base_addr = gpr_valobj_sp->GetAddressOf (true, &addr_type);
Greg Clayton37f962e2011-08-22 02:49:39 +0000159
160 ValueObjectSP child_valobj_sp;
161 if (gpr_valobj_sp)
162 {
163 ABI *abi = m_process->GetABI().get();
164 assert (abi);
165 uint32_t num_children = gpr_valobj_sp->GetNumChildren();
166
167 ConstString gpr_name (gpr_valobj_sp->GetName());
168 uint32_t reg_num = 0;
169 for (uint32_t i=0; i<num_children; ++i)
170 {
171 child_valobj_sp = gpr_valobj_sp->GetChildAtIndex(i, can_create);
172
173 ConstString reg_name(child_valobj_sp->GetName());
174 if (reg_name)
175 {
176 const char *reg_name_cstr = reg_name.GetCString();
177 while (reg_name_cstr[0] == '_')
178 ++reg_name_cstr;
179 if (reg_name_cstr != reg_name.GetCString())
180 reg_name.SetCString (reg_name_cstr);
181 }
182
183 RegisterInfo reg_info;
184 if (abi->GetRegisterInfoByName(reg_name, reg_info))
185 {
186 // Adjust the byte size and the offset to match the layout of registers in our struct
187 reg_info.byte_size = child_valobj_sp->GetByteSize();
Enrico Granata91544802011-09-06 19:20:51 +0000188 reg_info.byte_offset = child_valobj_sp->GetAddressOf(true, &addr_type) - base_addr;
Greg Clayton37f962e2011-08-22 02:49:39 +0000189 reg_info.kinds[eRegisterKindLLDB] = reg_num++;
190 m_register_info_ap->AddRegister (reg_info, reg_name, empty_name, gpr_name);
191 }
192 else
193 {
194 printf ("not able to find register info for %s\n", reg_name.GetCString()); // REMOVE THIS printf before checkin!!!
195 }
196 }
197
198 m_register_info_ap->Finalize();
199 }
200 }
201 assert (m_register_info_ap.get());
202 return m_register_info_ap.get();
203}
204
205//------------------------------------------------------------------
206// PluginInterface protocol
207//------------------------------------------------------------------
208const char *
Greg Clayton17f3d052011-08-22 22:30:57 +0000209OperatingSystemDarwinKernel::GetPluginName()
Greg Clayton37f962e2011-08-22 02:49:39 +0000210{
Greg Clayton17f3d052011-08-22 22:30:57 +0000211 return "OperatingSystemDarwinKernel";
Greg Clayton37f962e2011-08-22 02:49:39 +0000212}
213
214const char *
Greg Clayton17f3d052011-08-22 22:30:57 +0000215OperatingSystemDarwinKernel::GetShortPluginName()
Greg Clayton37f962e2011-08-22 02:49:39 +0000216{
217 return GetPluginNameStatic();
218}
219
220uint32_t
Greg Clayton17f3d052011-08-22 22:30:57 +0000221OperatingSystemDarwinKernel::GetPluginVersion()
Greg Clayton37f962e2011-08-22 02:49:39 +0000222{
223 return 1;
224}
225
226uint32_t
Greg Clayton17f3d052011-08-22 22:30:57 +0000227OperatingSystemDarwinKernel::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list)
Greg Clayton37f962e2011-08-22 02:49:39 +0000228{
229 // Make any constant strings once and cache the uniqued C string values
230 // so we don't have to rehash them each time through this function call
231 static ConstString g_tid_member_name("tid");
232 static ConstString g_next_member_name("next");
233
234 ValueObjectSP root_valobj_sp (GetThreadListValueObject ());
235 ValueObjectSP valobj_sp = root_valobj_sp;
236 const bool can_create = true;
237 while (valobj_sp)
238 {
239 if (valobj_sp->GetValueAsUnsigned(0) == 0)
240 break;
241
242 ValueObjectSP tid_valobj_sp(valobj_sp->GetChildMemberWithName(g_tid_member_name, can_create));
243 if (!tid_valobj_sp)
244 break;
245
246 tid_t tid = tid_valobj_sp->GetValueAsUnsigned (LLDB_INVALID_THREAD_ID);
247 if (tid == LLDB_INVALID_THREAD_ID)
248 break;
249
250 ThreadSP thread_sp (old_thread_list.FindThreadByID (tid, false));
251 if (!thread_sp)
Greg Claytonf4124de2012-02-21 00:09:25 +0000252 thread_sp.reset (new ThreadMemory (m_process->shared_from_this(), tid, valobj_sp));
Greg Clayton37f962e2011-08-22 02:49:39 +0000253
254 new_thread_list.AddThread(thread_sp);
255
256 ValueObjectSP next_valobj_sp (valobj_sp->GetChildMemberWithName(g_next_member_name, can_create));
257
258 if (next_valobj_sp)
259 {
260 // Watch for circular linked lists
261 if (next_valobj_sp.get() == root_valobj_sp.get())
262 break;
263 }
264 next_valobj_sp.swap(valobj_sp);
265 }
266 return new_thread_list.GetSize(false);
267}
268
269void
Greg Clayton17f3d052011-08-22 22:30:57 +0000270OperatingSystemDarwinKernel::ThreadWasSelected (Thread *thread)
Greg Clayton37f962e2011-08-22 02:49:39 +0000271{
272}
273
274RegisterContextSP
Greg Clayton17f3d052011-08-22 22:30:57 +0000275OperatingSystemDarwinKernel::CreateRegisterContextForThread (Thread *thread)
Greg Clayton37f962e2011-08-22 02:49:39 +0000276{
277 ThreadMemory *generic_thread = (ThreadMemory *)thread;
278 RegisterContextSP reg_ctx_sp;
279
280 ValueObjectSP thread_valobj_sp (generic_thread->GetValueObject());
281 if (thread_valobj_sp)
282 {
283 const bool can_create = true;
284 AddressType addr_type;
285 addr_t base_addr = LLDB_INVALID_ADDRESS;
286 ValueObjectSP gpr_valobj_sp (thread_valobj_sp->GetChildMemberWithName(GetThreadGPRMemberName (), can_create));
287 if (gpr_valobj_sp)
288 {
289 if (gpr_valobj_sp->IsPointerType ())
Enrico Granata91544802011-09-06 19:20:51 +0000290 base_addr = gpr_valobj_sp->GetPointerValue (&addr_type);
Greg Clayton37f962e2011-08-22 02:49:39 +0000291 else
Enrico Granata91544802011-09-06 19:20:51 +0000292 base_addr = gpr_valobj_sp->GetAddressOf (true, &addr_type);
Greg Clayton37f962e2011-08-22 02:49:39 +0000293 reg_ctx_sp.reset (new RegisterContextMemory (*thread, 0, *GetDynamicRegisterInfo (), base_addr));
294 }
295 }
296 return reg_ctx_sp;
297}
298
299StopInfoSP
Greg Clayton17f3d052011-08-22 22:30:57 +0000300OperatingSystemDarwinKernel::CreateThreadStopReason (lldb_private::Thread *thread)
Greg Clayton37f962e2011-08-22 02:49:39 +0000301{
302 StopInfoSP stop_info_sp; //(StopInfo::CreateStopReasonWithSignal (*thread, SIGSTOP));
303 return stop_info_sp;
304}
305
306