DynamicLoaderMacOSXDYLD.h [plain text]
#ifndef liblldb_DynamicLoaderMacOSXDYLD_h_
#define liblldb_DynamicLoaderMacOSXDYLD_h_
#include <map>
#include <vector>
#include <string>
#include "llvm/Support/MachO.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Core/UUID.h"
#include "lldb/Host/Mutex.h"
#include "lldb/Target/Process.h"
class DynamicLoaderMacOSXDYLD : public lldb_private::DynamicLoader
{
public:
static void
Initialize();
static void
Terminate();
static const char *
GetPluginNameStatic();
static const char *
GetPluginDescriptionStatic();
static lldb_private::DynamicLoader *
CreateInstance (lldb_private::Process *process, bool force);
DynamicLoaderMacOSXDYLD (lldb_private::Process *process);
virtual
~DynamicLoaderMacOSXDYLD ();
virtual void
DidAttach ();
virtual void
DidLaunch ();
virtual lldb::ThreadPlanSP
GetStepThroughTrampolinePlan (lldb_private::Thread &thread,
bool stop_others);
virtual lldb_private::Error
CanLoadImage ();
virtual const char *
GetPluginName();
virtual const char *
GetShortPluginName();
virtual uint32_t
GetPluginVersion();
protected:
void
PrivateInitialize (lldb_private::Process *process);
void
PrivateProcessStateChanged (lldb_private::Process *process,
lldb::StateType state);
bool
LocateDYLD ();
bool
DidSetNotificationBreakpoint () const;
void
Clear (bool clear_process);
void
PutToLog (lldb_private::Log *log) const;
bool
ReadDYLDInfoFromMemoryAndSetNotificationCallback (lldb::addr_t addr);
static bool
NotifyBreakpointHit (void *baton,
lldb_private::StoppointCallbackContext *context,
lldb::user_id_t break_id,
lldb::user_id_t break_loc_id);
uint32_t
AddrByteSize()
{
switch (m_dyld.header.magic)
{
case llvm::MachO::HeaderMagic32:
case llvm::MachO::HeaderMagic32Swapped:
return 4;
case llvm::MachO::HeaderMagic64:
case llvm::MachO::HeaderMagic64Swapped:
return 8;
default:
break;
}
return 0;
}
static lldb::ByteOrder
GetByteOrderFromMagic (uint32_t magic)
{
switch (magic)
{
case llvm::MachO::HeaderMagic32:
case llvm::MachO::HeaderMagic64:
return lldb::endian::InlHostByteOrder();
case llvm::MachO::HeaderMagic32Swapped:
case llvm::MachO::HeaderMagic64Swapped:
if (lldb::endian::InlHostByteOrder() == lldb::eByteOrderBig)
return lldb::eByteOrderLittle;
else
return lldb::eByteOrderBig;
default:
break;
}
return lldb::eByteOrderInvalid;
}
bool
ReadMachHeader (lldb::addr_t addr,
llvm::MachO::mach_header *header,
lldb_private::DataExtractor *load_command_data);
class Segment
{
public:
Segment() :
name(),
vmaddr(LLDB_INVALID_ADDRESS),
vmsize(0),
fileoff(0),
filesize(0),
maxprot(0),
initprot(0),
nsects(0),
flags(0)
{
}
lldb_private::ConstString name;
lldb::addr_t vmaddr;
lldb::addr_t vmsize;
lldb::addr_t fileoff;
lldb::addr_t filesize;
uint32_t maxprot;
uint32_t initprot;
uint32_t nsects;
uint32_t flags;
bool
operator==(const Segment& rhs) const
{
return name == rhs.name && vmaddr == rhs.vmaddr && vmsize == rhs.vmsize;
}
void
PutToLog (lldb_private::Log *log,
lldb::addr_t slide) const;
};
struct DYLDImageInfo
{
lldb::addr_t address; lldb::addr_t slide; lldb::addr_t mod_date; lldb_private::FileSpec file_spec; lldb_private::UUID uuid; llvm::MachO::mach_header header; std::vector<Segment> segments;
DYLDImageInfo() :
address(LLDB_INVALID_ADDRESS),
slide(0),
mod_date(0),
file_spec(),
uuid(),
header(),
segments()
{
}
void
Clear(bool load_cmd_data_only)
{
if (!load_cmd_data_only)
{
address = LLDB_INVALID_ADDRESS;
slide = 0;
mod_date = 0;
file_spec.Clear();
::memset (&header, 0, sizeof(header));
}
uuid.Clear();
segments.clear();
}
bool
operator == (const DYLDImageInfo& rhs) const
{
return address == rhs.address
&& slide == rhs.slide
&& mod_date == rhs.mod_date
&& file_spec == rhs.file_spec
&& uuid == rhs.uuid
&& memcmp(&header, &rhs.header, sizeof(header)) == 0
&& segments == rhs.segments;
}
bool
UUIDValid() const
{
return uuid.IsValid();
}
uint32_t
GetAddressByteSize ()
{
if (header.cputype)
{
if (header.cputype & llvm::MachO::CPUArchABI64)
return 8;
else
return 4;
}
return 0;
}
lldb::ByteOrder
GetByteOrder()
{
switch (header.magic)
{
case llvm::MachO::HeaderMagic32: case llvm::MachO::HeaderMagic64: return lldb::endian::InlHostByteOrder();
case llvm::MachO::HeaderMagic32Swapped: case llvm::MachO::HeaderMagic64Swapped: if (lldb::endian::InlHostByteOrder() == lldb::eByteOrderLittle)
return lldb::eByteOrderBig;
else
return lldb::eByteOrderLittle;
default:
assert (!"invalid header.magic value");
break;
}
return lldb::endian::InlHostByteOrder();
}
lldb_private::ArchSpec
GetArchitecture () const
{
return lldb_private::ArchSpec (lldb_private::eArchTypeMachO, header.cputype, header.cpusubtype);
}
const Segment *
FindSegment (const lldb_private::ConstString &name) const;
void
PutToLog (lldb_private::Log *log) const;
typedef std::vector<DYLDImageInfo> collection;
typedef collection::iterator iterator;
typedef collection::const_iterator const_iterator;
};
struct DYLDAllImageInfos
{
uint32_t version;
uint32_t dylib_info_count; lldb::addr_t dylib_info_addr; lldb::addr_t notification; bool processDetachedFromSharedRegion; bool libSystemInitialized; lldb::addr_t dyldImageLoadAddress;
DYLDAllImageInfos() :
version (0),
dylib_info_count (0),
dylib_info_addr (LLDB_INVALID_ADDRESS),
notification (LLDB_INVALID_ADDRESS),
processDetachedFromSharedRegion (false),
libSystemInitialized (false),
dyldImageLoadAddress (LLDB_INVALID_ADDRESS)
{
}
void
Clear()
{
version = 0;
dylib_info_count = 0;
dylib_info_addr = LLDB_INVALID_ADDRESS;
notification = LLDB_INVALID_ADDRESS;
processDetachedFromSharedRegion = false;
libSystemInitialized = false;
dyldImageLoadAddress = LLDB_INVALID_ADDRESS;
}
bool
IsValid() const
{
return version >= 1 || version <= 6;
}
};
void
RegisterNotificationCallbacks();
void
UnregisterNotificationCallbacks();
uint32_t
ParseLoadCommands (const lldb_private::DataExtractor& data,
DYLDImageInfo& dylib_info,
lldb_private::FileSpec *lc_id_dylinker);
bool
UpdateImageLoadAddress(lldb_private::Module *module,
DYLDImageInfo& info);
bool
UnloadImageLoadAddress (lldb_private::Module *module,
DYLDImageInfo& info);
lldb::ModuleSP
FindTargetModuleForDYLDImageInfo (const DYLDImageInfo &image_info,
bool can_create,
bool *did_create_ptr);
DYLDImageInfo *
GetImageInfo (lldb_private::Module *module);
bool
NeedToLocateDYLD () const;
bool
SetNotificationBreakpoint ();
bool
InitializeFromAllImageInfos ();
bool
ReadAllImageInfosStructure ();
bool
AddModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count);
bool
AddModulesUsingImageInfos (DYLDImageInfo::collection &image_infos);
bool
RemoveModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count);
void
UpdateImageInfosHeaderAndLoadCommands(DYLDImageInfo::collection &image_infos,
uint32_t infos_count,
bool update_executable);
bool
UpdateCommPageLoadAddress (lldb_private::Module *module);
bool
ReadImageInfos (lldb::addr_t image_infos_addr,
uint32_t image_infos_count,
DYLDImageInfo::collection &image_infos);
DYLDImageInfo m_dyld; lldb::addr_t m_dyld_all_image_infos_addr;
DYLDAllImageInfos m_dyld_all_image_infos;
uint32_t m_dyld_all_image_infos_stop_id;
lldb::user_id_t m_break_id;
DYLDImageInfo::collection m_dyld_image_infos; uint32_t m_dyld_image_infos_stop_id; mutable lldb_private::Mutex m_mutex;
lldb_private::Process::Notifications m_notification_callbacks;
private:
DISALLOW_COPY_AND_ASSIGN (DynamicLoaderMacOSXDYLD);
};
#endif // liblldb_DynamicLoaderMacOSXDYLD_h_