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