1e996fd30SGreg Clayton //===-- PlatformLinux.cpp ---------------------------------------*- C++ -*-===//
2e996fd30SGreg Clayton //
3e996fd30SGreg Clayton //                     The LLVM Compiler Infrastructure
4e996fd30SGreg Clayton //
5e996fd30SGreg Clayton // This file is distributed under the University of Illinois Open Source
6e996fd30SGreg Clayton // License. See LICENSE.TXT for details.
7e996fd30SGreg Clayton //
8e996fd30SGreg Clayton //===----------------------------------------------------------------------===//
9e996fd30SGreg Clayton 
10e996fd30SGreg Clayton #include "PlatformLinux.h"
11e996fd30SGreg Clayton 
12e996fd30SGreg Clayton // C Includes
13ecc11474SStephen Wilson #include <stdio.h>
14ecc11474SStephen Wilson #include <sys/utsname.h>
15ecc11474SStephen Wilson 
16e996fd30SGreg Clayton // C++ Includes
17e996fd30SGreg Clayton // Other libraries and framework includes
18e996fd30SGreg Clayton // Project includes
19e996fd30SGreg Clayton #include "lldb/Core/Error.h"
20e996fd30SGreg Clayton #include "lldb/Core/Module.h"
21e996fd30SGreg Clayton #include "lldb/Core/ModuleList.h"
22ecc11474SStephen Wilson #include "lldb/Core/PluginManager.h"
23e996fd30SGreg Clayton #include "lldb/Core/StreamString.h"
24e996fd30SGreg Clayton #include "lldb/Host/FileSpec.h"
25e996fd30SGreg Clayton #include "lldb/Host/Host.h"
26ecc11474SStephen Wilson #include "lldb/Target/Target.h"
27e996fd30SGreg Clayton #include "lldb/Target/Process.h"
28e996fd30SGreg Clayton 
29e996fd30SGreg Clayton using namespace lldb;
30e996fd30SGreg Clayton using namespace lldb_private;
31e996fd30SGreg Clayton 
32ecc11474SStephen Wilson Platform *
33ecc11474SStephen Wilson PlatformLinux::CreateInstance ()
34ecc11474SStephen Wilson {
35ecc11474SStephen Wilson     return new PlatformLinux();
36ecc11474SStephen Wilson }
37ecc11474SStephen Wilson 
38ecc11474SStephen Wilson const char *
39ecc11474SStephen Wilson PlatformLinux::GetPluginNameStatic()
40ecc11474SStephen Wilson {
41ecc11474SStephen Wilson     return "plugin.platform.linux";
42ecc11474SStephen Wilson }
43ecc11474SStephen Wilson 
44ecc11474SStephen Wilson const char *
45ecc11474SStephen Wilson PlatformLinux::GetPluginDescriptionStatic()
46ecc11474SStephen Wilson {
47ecc11474SStephen Wilson     return "Default platform plugin for Linux";
48ecc11474SStephen Wilson }
49ecc11474SStephen Wilson 
50e996fd30SGreg Clayton void
51e996fd30SGreg Clayton PlatformLinux::Initialize ()
52e996fd30SGreg Clayton {
53ecc11474SStephen Wilson     static bool g_initialized = false;
54ecc11474SStephen Wilson 
55ecc11474SStephen Wilson     if (!g_initialized)
56ecc11474SStephen Wilson     {
57ecc11474SStephen Wilson         PlatformSP default_platform_sp (CreateInstance());
58e996fd30SGreg Clayton         Platform::SetDefaultPlatform (default_platform_sp);
59ecc11474SStephen Wilson         PluginManager::RegisterPlugin(GetPluginNameStatic(),
60ecc11474SStephen Wilson                                       GetPluginDescriptionStatic(),
61ecc11474SStephen Wilson                                       CreateInstance);
62ecc11474SStephen Wilson         g_initialized = true;
63ecc11474SStephen Wilson     }
64e996fd30SGreg Clayton }
65e996fd30SGreg Clayton 
66e996fd30SGreg Clayton void
67e996fd30SGreg Clayton PlatformLinux::Terminate ()
68e996fd30SGreg Clayton {
69e996fd30SGreg Clayton }
70e996fd30SGreg Clayton 
71e996fd30SGreg Clayton 
72e996fd30SGreg Clayton Error
73e996fd30SGreg Clayton PlatformLinux::ResolveExecutable (const FileSpec &exe_file,
74e996fd30SGreg Clayton                                   const ArchSpec &exe_arch,
75e996fd30SGreg Clayton                                   lldb::ModuleSP &exe_module_sp)
76e996fd30SGreg Clayton {
77e996fd30SGreg Clayton     Error error;
78e996fd30SGreg Clayton     // Nothing special to do here, just use the actual file and architecture
79e996fd30SGreg Clayton 
80e996fd30SGreg Clayton     FileSpec resolved_exe_file (exe_file);
81e996fd30SGreg Clayton 
82e996fd30SGreg Clayton     // If we have "ls" as the exe_file, resolve the executable loation based on
83e996fd30SGreg Clayton     // the current path variables
84e996fd30SGreg Clayton     if (!resolved_exe_file.Exists())
85e996fd30SGreg Clayton         resolved_exe_file.ResolveExecutableLocation ();
86e996fd30SGreg Clayton 
87e996fd30SGreg Clayton     // Resolve any executable within a bundle on MacOSX
88e996fd30SGreg Clayton     Host::ResolveExecutableInBundle (resolved_exe_file);
89e996fd30SGreg Clayton 
90e996fd30SGreg Clayton     if (resolved_exe_file.Exists())
91e996fd30SGreg Clayton     {
92e996fd30SGreg Clayton         if (exe_arch.IsValid())
93e996fd30SGreg Clayton         {
94e996fd30SGreg Clayton             error = ModuleList::GetSharedModule (resolved_exe_file,
95e996fd30SGreg Clayton                                                  exe_arch,
96e996fd30SGreg Clayton                                                  NULL,
97e996fd30SGreg Clayton                                                  NULL,
98e996fd30SGreg Clayton                                                  0,
99e996fd30SGreg Clayton                                                  exe_module_sp,
100e996fd30SGreg Clayton                                                  NULL,
101e996fd30SGreg Clayton                                                  NULL);
102e996fd30SGreg Clayton 
103e996fd30SGreg Clayton             if (exe_module_sp->GetObjectFile() == NULL)
104e996fd30SGreg Clayton             {
105e996fd30SGreg Clayton                 exe_module_sp.reset();
106e996fd30SGreg Clayton                 error.SetErrorStringWithFormat ("'%s%s%s' doesn't contain the architecture %s",
107e996fd30SGreg Clayton                                                 exe_file.GetDirectory().AsCString(""),
108e996fd30SGreg Clayton                                                 exe_file.GetDirectory() ? "/" : "",
109e996fd30SGreg Clayton                                                 exe_file.GetFilename().AsCString(""),
110e996fd30SGreg Clayton                                                 exe_arch.GetArchitectureName());
111e996fd30SGreg Clayton             }
112e996fd30SGreg Clayton         }
113e996fd30SGreg Clayton         else
114e996fd30SGreg Clayton         {
115e996fd30SGreg Clayton             // No valid architecture was specified, ask the platform for
116e996fd30SGreg Clayton             // the architectures that we should be using (in the correct order)
117e996fd30SGreg Clayton             // and see if we can find a match that way
118e996fd30SGreg Clayton             StreamString arch_names;
119e996fd30SGreg Clayton             ArchSpec platform_arch;
120e996fd30SGreg Clayton             for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, platform_arch); ++idx)
121e996fd30SGreg Clayton             {
122e996fd30SGreg Clayton                 error = ModuleList::GetSharedModule (resolved_exe_file,
123e996fd30SGreg Clayton                                                      platform_arch,
124e996fd30SGreg Clayton                                                      NULL,
125e996fd30SGreg Clayton                                                      NULL,
126e996fd30SGreg Clayton                                                      0,
127e996fd30SGreg Clayton                                                      exe_module_sp,
128e996fd30SGreg Clayton                                                      NULL,
129e996fd30SGreg Clayton                                                      NULL);
130e996fd30SGreg Clayton                 // Did we find an executable using one of the
131e996fd30SGreg Clayton                 if (error.Success())
132e996fd30SGreg Clayton                 {
133e996fd30SGreg Clayton                     if (exe_module_sp && exe_module_sp->GetObjectFile())
134e996fd30SGreg Clayton                         break;
135e996fd30SGreg Clayton                     else
136e996fd30SGreg Clayton                         error.SetErrorToGenericError();
137e996fd30SGreg Clayton                 }
138e996fd30SGreg Clayton 
139e996fd30SGreg Clayton                 if (idx > 0)
140e996fd30SGreg Clayton                     arch_names.PutCString (", ");
141e996fd30SGreg Clayton                 arch_names.PutCString (platform_arch.GetArchitectureName());
142e996fd30SGreg Clayton             }
143e996fd30SGreg Clayton 
144e996fd30SGreg Clayton             if (error.Fail() || !exe_module_sp)
145e996fd30SGreg Clayton             {
146e996fd30SGreg Clayton                 error.SetErrorStringWithFormat ("'%s%s%s' doesn't contain any '%s' platform architectures: %s",
147e996fd30SGreg Clayton                                                 exe_file.GetDirectory().AsCString(""),
148e996fd30SGreg Clayton                                                 exe_file.GetDirectory() ? "/" : "",
149e996fd30SGreg Clayton                                                 exe_file.GetFilename().AsCString(""),
150e996fd30SGreg Clayton                                                 GetShortPluginName(),
151e996fd30SGreg Clayton                                                 arch_names.GetString().c_str());
152e996fd30SGreg Clayton             }
153e996fd30SGreg Clayton         }
154e996fd30SGreg Clayton     }
155e996fd30SGreg Clayton     else
156e996fd30SGreg Clayton     {
157e996fd30SGreg Clayton         error.SetErrorStringWithFormat ("'%s%s%s' does not exist",
158e996fd30SGreg Clayton                                         exe_file.GetDirectory().AsCString(""),
159e996fd30SGreg Clayton                                         exe_file.GetDirectory() ? "/" : "",
160e996fd30SGreg Clayton                                         exe_file.GetFilename().AsCString(""));
161e996fd30SGreg Clayton     }
162e996fd30SGreg Clayton 
163e996fd30SGreg Clayton     return error;
164e996fd30SGreg Clayton }
165e996fd30SGreg Clayton 
166e996fd30SGreg Clayton Error
16778decfd0SStephen Wilson PlatformLinux::GetFile (const FileSpec &platform_file,
16878decfd0SStephen Wilson                         const UUID *uuid, FileSpec &local_file)
169e996fd30SGreg Clayton {
170e996fd30SGreg Clayton     // Default to the local case
171e996fd30SGreg Clayton     local_file = platform_file;
172e996fd30SGreg Clayton     return Error();
173e996fd30SGreg Clayton }
174e996fd30SGreg Clayton 
175e996fd30SGreg Clayton 
176e996fd30SGreg Clayton //------------------------------------------------------------------
177e996fd30SGreg Clayton /// Default Constructor
178e996fd30SGreg Clayton //------------------------------------------------------------------
179e996fd30SGreg Clayton PlatformLinux::PlatformLinux () :
180ecc11474SStephen Wilson     Platform(true)
181e996fd30SGreg Clayton {
182e996fd30SGreg Clayton }
183e996fd30SGreg Clayton 
184e996fd30SGreg Clayton //------------------------------------------------------------------
185e996fd30SGreg Clayton /// Destructor.
186e996fd30SGreg Clayton ///
187e996fd30SGreg Clayton /// The destructor is virtual since this class is designed to be
188e996fd30SGreg Clayton /// inherited from by the plug-in instance.
189e996fd30SGreg Clayton //------------------------------------------------------------------
190e996fd30SGreg Clayton PlatformLinux::~PlatformLinux()
191e996fd30SGreg Clayton {
192e996fd30SGreg Clayton }
193e996fd30SGreg Clayton 
194e996fd30SGreg Clayton bool
19513e8e1c3SJohnny Chen PlatformLinux::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
196e996fd30SGreg Clayton {
197e996fd30SGreg Clayton     return Host::GetProcessInfo (pid, process_info);
198e996fd30SGreg Clayton }
199e996fd30SGreg Clayton 
200e996fd30SGreg Clayton bool
201e996fd30SGreg Clayton PlatformLinux::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
202e996fd30SGreg Clayton {
203e996fd30SGreg Clayton     if (idx == 0)
204e996fd30SGreg Clayton     {
205e996fd30SGreg Clayton         arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture);
206e996fd30SGreg Clayton         return arch.IsValid();
207e996fd30SGreg Clayton     }
208e996fd30SGreg Clayton     return false;
209e996fd30SGreg Clayton }
210ecc11474SStephen Wilson 
211ecc11474SStephen Wilson void
212ecc11474SStephen Wilson PlatformLinux::GetStatus (Stream &strm)
213ecc11474SStephen Wilson {
214ecc11474SStephen Wilson     struct utsname un;
215ecc11474SStephen Wilson 
216ecc11474SStephen Wilson     if (uname(&un)) {
217ecc11474SStephen Wilson         strm << "Linux";
218ecc11474SStephen Wilson         return;
219ecc11474SStephen Wilson     }
220ecc11474SStephen Wilson 
221ecc11474SStephen Wilson     strm << un.sysname << ' ' << un.release << ' ' << un.version << '\n';
222ecc11474SStephen Wilson }
223ecc11474SStephen Wilson 
224ecc11474SStephen Wilson size_t
225ecc11474SStephen Wilson PlatformLinux::GetSoftwareBreakpointTrapOpcode (Target &target,
226ecc11474SStephen Wilson                                                 BreakpointSite *bp_site)
227ecc11474SStephen Wilson {
228ecc11474SStephen Wilson     static const uint8_t g_i386_opcode[] = { 0xCC };
229ecc11474SStephen Wilson 
230ecc11474SStephen Wilson     ArchSpec arch = target.GetArchitecture();
231ecc11474SStephen Wilson     const uint8_t *opcode = NULL;
232ecc11474SStephen Wilson     size_t opcode_size = 0;
233ecc11474SStephen Wilson 
234ecc11474SStephen Wilson     switch (arch.GetCore())
235ecc11474SStephen Wilson     {
236ecc11474SStephen Wilson     default:
237ecc11474SStephen Wilson         assert(false && "CPU type not supported!");
238ecc11474SStephen Wilson         break;
239ecc11474SStephen Wilson 
240ecc11474SStephen Wilson     case ArchSpec::eCore_x86_32_i386:
241ecc11474SStephen Wilson     case ArchSpec::eCore_x86_64_x86_64:
242ecc11474SStephen Wilson         opcode = g_i386_opcode;
243ecc11474SStephen Wilson         opcode_size = sizeof(g_i386_opcode);
244ecc11474SStephen Wilson         break;
245ecc11474SStephen Wilson     }
246ecc11474SStephen Wilson 
247ecc11474SStephen Wilson     bp_site->SetTrapOpcode(opcode, opcode_size);
248ecc11474SStephen Wilson     return opcode_size;
249ecc11474SStephen Wilson }
25013e8e1c3SJohnny Chen 
25113e8e1c3SJohnny Chen lldb::ProcessSP
252*fb2b629dSPeter Collingbourne PlatformLinux::Attach(ProcessAttachInfo &attach_info,
25313e8e1c3SJohnny Chen                       Debugger &debugger,
25413e8e1c3SJohnny Chen                       Target *target,
25513e8e1c3SJohnny Chen                       Listener &listener,
25613e8e1c3SJohnny Chen                       Error &error)
25713e8e1c3SJohnny Chen {
25813e8e1c3SJohnny Chen     ProcessSP processSP;
25913e8e1c3SJohnny Chen     assert(!"Not implemented yet!");
26013e8e1c3SJohnny Chen     return processSP;
26113e8e1c3SJohnny Chen }
262