2011-03-09 06:40:15 +08:00
|
|
|
//===-- PlatformLinux.cpp ---------------------------------------*- C++ -*-===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "PlatformLinux.h"
|
|
|
|
|
|
|
|
// C Includes
|
2011-03-23 08:57:47 +08:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <sys/utsname.h>
|
|
|
|
|
2011-03-09 06:40:15 +08:00
|
|
|
// C++ Includes
|
|
|
|
// Other libraries and framework includes
|
|
|
|
// Project includes
|
|
|
|
#include "lldb/Core/Error.h"
|
|
|
|
#include "lldb/Core/Module.h"
|
|
|
|
#include "lldb/Core/ModuleList.h"
|
2011-03-23 08:57:47 +08:00
|
|
|
#include "lldb/Core/PluginManager.h"
|
2011-03-09 06:40:15 +08:00
|
|
|
#include "lldb/Core/StreamString.h"
|
|
|
|
#include "lldb/Host/FileSpec.h"
|
|
|
|
#include "lldb/Host/Host.h"
|
2011-03-23 08:57:47 +08:00
|
|
|
#include "lldb/Target/Target.h"
|
2011-03-09 06:40:15 +08:00
|
|
|
#include "lldb/Target/Process.h"
|
|
|
|
|
|
|
|
using namespace lldb;
|
|
|
|
using namespace lldb_private;
|
2011-03-23 08:57:47 +08:00
|
|
|
|
|
|
|
Platform *
|
|
|
|
PlatformLinux::CreateInstance ()
|
|
|
|
{
|
|
|
|
return new PlatformLinux();
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *
|
|
|
|
PlatformLinux::GetPluginNameStatic()
|
|
|
|
{
|
|
|
|
return "plugin.platform.linux";
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *
|
|
|
|
PlatformLinux::GetPluginDescriptionStatic()
|
|
|
|
{
|
|
|
|
return "Default platform plugin for Linux";
|
|
|
|
}
|
|
|
|
|
2011-03-09 06:40:15 +08:00
|
|
|
void
|
|
|
|
PlatformLinux::Initialize ()
|
|
|
|
{
|
2011-03-23 08:57:47 +08:00
|
|
|
static bool g_initialized = false;
|
|
|
|
|
|
|
|
if (!g_initialized)
|
|
|
|
{
|
|
|
|
PlatformSP default_platform_sp (CreateInstance());
|
|
|
|
Platform::SetDefaultPlatform (default_platform_sp);
|
|
|
|
PluginManager::RegisterPlugin(GetPluginNameStatic(),
|
|
|
|
GetPluginDescriptionStatic(),
|
|
|
|
CreateInstance);
|
|
|
|
g_initialized = true;
|
|
|
|
}
|
2011-03-09 06:40:15 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
PlatformLinux::Terminate ()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Error
|
|
|
|
PlatformLinux::ResolveExecutable (const FileSpec &exe_file,
|
|
|
|
const ArchSpec &exe_arch,
|
|
|
|
lldb::ModuleSP &exe_module_sp)
|
|
|
|
{
|
|
|
|
Error error;
|
|
|
|
// Nothing special to do here, just use the actual file and architecture
|
|
|
|
|
|
|
|
FileSpec resolved_exe_file (exe_file);
|
|
|
|
|
|
|
|
// If we have "ls" as the exe_file, resolve the executable loation based on
|
|
|
|
// the current path variables
|
|
|
|
if (!resolved_exe_file.Exists())
|
|
|
|
resolved_exe_file.ResolveExecutableLocation ();
|
|
|
|
|
|
|
|
// Resolve any executable within a bundle on MacOSX
|
|
|
|
Host::ResolveExecutableInBundle (resolved_exe_file);
|
|
|
|
|
|
|
|
if (resolved_exe_file.Exists())
|
|
|
|
{
|
|
|
|
if (exe_arch.IsValid())
|
|
|
|
{
|
|
|
|
error = ModuleList::GetSharedModule (resolved_exe_file,
|
|
|
|
exe_arch,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
exe_module_sp,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
if (exe_module_sp->GetObjectFile() == NULL)
|
|
|
|
{
|
|
|
|
exe_module_sp.reset();
|
|
|
|
error.SetErrorStringWithFormat ("'%s%s%s' doesn't contain the architecture %s",
|
|
|
|
exe_file.GetDirectory().AsCString(""),
|
|
|
|
exe_file.GetDirectory() ? "/" : "",
|
|
|
|
exe_file.GetFilename().AsCString(""),
|
|
|
|
exe_arch.GetArchitectureName());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// No valid architecture was specified, ask the platform for
|
|
|
|
// the architectures that we should be using (in the correct order)
|
|
|
|
// and see if we can find a match that way
|
|
|
|
StreamString arch_names;
|
|
|
|
ArchSpec platform_arch;
|
|
|
|
for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, platform_arch); ++idx)
|
|
|
|
{
|
|
|
|
error = ModuleList::GetSharedModule (resolved_exe_file,
|
|
|
|
platform_arch,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
exe_module_sp,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
// Did we find an executable using one of the
|
|
|
|
if (error.Success())
|
|
|
|
{
|
|
|
|
if (exe_module_sp && exe_module_sp->GetObjectFile())
|
|
|
|
break;
|
|
|
|
else
|
|
|
|
error.SetErrorToGenericError();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (idx > 0)
|
|
|
|
arch_names.PutCString (", ");
|
|
|
|
arch_names.PutCString (platform_arch.GetArchitectureName());
|
|
|
|
}
|
|
|
|
|
|
|
|
if (error.Fail() || !exe_module_sp)
|
|
|
|
{
|
|
|
|
error.SetErrorStringWithFormat ("'%s%s%s' doesn't contain any '%s' platform architectures: %s",
|
|
|
|
exe_file.GetDirectory().AsCString(""),
|
|
|
|
exe_file.GetDirectory() ? "/" : "",
|
|
|
|
exe_file.GetFilename().AsCString(""),
|
|
|
|
GetShortPluginName(),
|
|
|
|
arch_names.GetString().c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
error.SetErrorStringWithFormat ("'%s%s%s' does not exist",
|
|
|
|
exe_file.GetDirectory().AsCString(""),
|
|
|
|
exe_file.GetDirectory() ? "/" : "",
|
|
|
|
exe_file.GetFilename().AsCString(""));
|
|
|
|
}
|
|
|
|
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
Error
|
2011-03-26 08:34:57 +08:00
|
|
|
PlatformLinux::GetFile (const FileSpec &platform_file,
|
|
|
|
const UUID *uuid, FileSpec &local_file)
|
2011-03-09 06:40:15 +08:00
|
|
|
{
|
|
|
|
// Default to the local case
|
|
|
|
local_file = platform_file;
|
|
|
|
return Error();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
/// Default Constructor
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
PlatformLinux::PlatformLinux () :
|
2011-03-23 08:57:47 +08:00
|
|
|
Platform(true)
|
2011-03-09 06:40:15 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
/// Destructor.
|
|
|
|
///
|
|
|
|
/// The destructor is virtual since this class is designed to be
|
|
|
|
/// inherited from by the plug-in instance.
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
PlatformLinux::~PlatformLinux()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2011-05-14 05:29:50 +08:00
|
|
|
PlatformLinux::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
|
2011-03-09 06:40:15 +08:00
|
|
|
{
|
|
|
|
return Host::GetProcessInfo (pid, process_info);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
PlatformLinux::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
|
|
|
|
{
|
|
|
|
if (idx == 0)
|
|
|
|
{
|
|
|
|
arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture);
|
|
|
|
return arch.IsValid();
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2011-03-23 08:57:47 +08:00
|
|
|
|
|
|
|
void
|
|
|
|
PlatformLinux::GetStatus (Stream &strm)
|
|
|
|
{
|
|
|
|
struct utsname un;
|
|
|
|
|
|
|
|
if (uname(&un)) {
|
|
|
|
strm << "Linux";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
strm << un.sysname << ' ' << un.release << ' ' << un.version << '\n';
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t
|
|
|
|
PlatformLinux::GetSoftwareBreakpointTrapOpcode (Target &target,
|
|
|
|
BreakpointSite *bp_site)
|
|
|
|
{
|
|
|
|
static const uint8_t g_i386_opcode[] = { 0xCC };
|
|
|
|
|
|
|
|
ArchSpec arch = target.GetArchitecture();
|
|
|
|
const uint8_t *opcode = NULL;
|
|
|
|
size_t opcode_size = 0;
|
|
|
|
|
|
|
|
switch (arch.GetCore())
|
|
|
|
{
|
|
|
|
default:
|
|
|
|
assert(false && "CPU type not supported!");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ArchSpec::eCore_x86_32_i386:
|
|
|
|
case ArchSpec::eCore_x86_64_x86_64:
|
|
|
|
opcode = g_i386_opcode;
|
|
|
|
opcode_size = sizeof(g_i386_opcode);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
bp_site->SetTrapOpcode(opcode, opcode_size);
|
|
|
|
return opcode_size;
|
|
|
|
}
|
2011-05-14 05:29:50 +08:00
|
|
|
|
|
|
|
lldb::ProcessSP
|
2011-11-21 08:10:14 +08:00
|
|
|
PlatformLinux::Attach(ProcessAttachInfo &attach_info,
|
2011-05-14 05:29:50 +08:00
|
|
|
Debugger &debugger,
|
|
|
|
Target *target,
|
|
|
|
Listener &listener,
|
|
|
|
Error &error)
|
|
|
|
{
|
|
|
|
ProcessSP processSP;
|
|
|
|
assert(!"Not implemented yet!");
|
|
|
|
return processSP;
|
|
|
|
}
|