summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/DynamicLoader/MacOSX-Kernel/DynamicLoaderMacOSXKernel.h
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2011-07-08 00:48:09 +0000
committerGreg Clayton <gclayton@apple.com>2011-07-08 00:48:09 +0000
commit7b242381b8cf1878d669922d5a93b42eb59f526f (patch)
tree942b8179fefc11f57d89e84adc7dd6430e4fdcf2 /lldb/source/Plugins/DynamicLoader/MacOSX-Kernel/DynamicLoaderMacOSXKernel.h
parentf9a85356bcdb397909d5821183abdb827be59dda (diff)
downloadbcm5719-llvm-7b242381b8cf1878d669922d5a93b42eb59f526f.tar.gz
bcm5719-llvm-7b242381b8cf1878d669922d5a93b42eb59f526f.zip
Added the start of the darwin dynamic loader plug-in. It isn't hooked up to
be detected yet, but most of the initial code is there and needs to be debugged more. llvm-svn: 134672
Diffstat (limited to 'lldb/source/Plugins/DynamicLoader/MacOSX-Kernel/DynamicLoaderMacOSXKernel.h')
-rw-r--r--lldb/source/Plugins/DynamicLoader/MacOSX-Kernel/DynamicLoaderMacOSXKernel.h418
1 files changed, 418 insertions, 0 deletions
diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-Kernel/DynamicLoaderMacOSXKernel.h b/lldb/source/Plugins/DynamicLoader/MacOSX-Kernel/DynamicLoaderMacOSXKernel.h
new file mode 100644
index 00000000000..7dbd98db2ab
--- /dev/null
+++ b/lldb/source/Plugins/DynamicLoader/MacOSX-Kernel/DynamicLoaderMacOSXKernel.h
@@ -0,0 +1,418 @@
+//===-- DynamicLoaderMacOSXKernel.h -----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_DynamicLoaderMacOSXKernel_h_
+#define liblldb_DynamicLoaderMacOSXKernel_h_
+
+// C Includes
+// C++ Includes
+#include <map>
+#include <vector>
+#include <string>
+
+// Other libraries and framework includes
+#include "llvm/Support/MachO.h"
+
+#include "lldb/Target/DynamicLoader.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Host/TimeValue.h"
+#include "lldb/Core/UUID.h"
+#include "lldb/Host/Mutex.h"
+#include "lldb/Target/Process.h"
+
+class DynamicLoaderMacOSXKernel : public lldb_private::DynamicLoader
+{
+public:
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ 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);
+
+ DynamicLoaderMacOSXKernel (lldb_private::Process *process);
+
+ virtual
+ ~DynamicLoaderMacOSXKernel ();
+ //------------------------------------------------------------------
+ /// Called after attaching a process.
+ ///
+ /// Allow DynamicLoader plug-ins to execute some code after
+ /// attaching to a process.
+ //------------------------------------------------------------------
+ virtual void
+ DidAttach ();
+
+ virtual void
+ DidLaunch ();
+
+ virtual lldb::ThreadPlanSP
+ GetStepThroughTrampolinePlan (lldb_private::Thread &thread,
+ bool stop_others);
+
+ virtual lldb_private::Error
+ CanLoadImage ();
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ 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
+ LoadKernelModule ();
+
+ bool
+ DidSetNotificationBreakpoint () const;
+
+ void
+ Clear (bool clear_process);
+
+ void
+ PutToLog (lldb_private::Log *log) const;
+
+ 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_kernel.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;
+
+ };
+
+ enum { KERNEL_MODULE_MAX_NAME = 64u };
+
+ struct OSKextLoadedKextSummary
+ {
+ char name[KERNEL_MODULE_MAX_NAME];
+ lldb::ModuleSP module_sp;
+ lldb_private::UUID uuid; // UUID for this dylib if it has one, else all zeros
+ uint64_t address;
+ uint64_t size;
+ uint64_t version;
+ uint32_t load_tag;
+ uint32_t flags;
+ uint64_t reference_list;
+ llvm::MachO::mach_header header; // The mach header for this image
+ std::vector<Segment> segments; // All segment vmaddr and vmsize pairs for this executable (from memory of inferior)
+
+ OSKextLoadedKextSummary() :
+ module_sp (),
+ uuid (),
+ address (LLDB_INVALID_ADDRESS),
+ size (0),
+ version (0),
+ load_tag (0),
+ flags (0),
+ reference_list (0),
+ header(),
+ segments()
+ {
+ name[0] = '\0';
+ }
+
+ void
+ Clear (bool load_cmd_data_only)
+ {
+ if (!load_cmd_data_only)
+ {
+ address = LLDB_INVALID_ADDRESS;
+ size = 0;
+ version = 0;
+ load_tag = 0;
+ flags = 0;
+ reference_list = 0;
+ name[0] = '\0';
+ ::memset (&header, 0, sizeof(header));
+ }
+ module_sp.reset();
+ uuid.Clear();
+ segments.clear();
+ }
+
+ bool
+ operator == (const OSKextLoadedKextSummary& rhs) const
+ {
+ return address == rhs.address
+ && size == rhs.size
+ //&& module_sp.get() == rhs.module_sp.get()
+ && uuid == rhs.uuid
+ && version == rhs.version
+ && load_tag == rhs.load_tag
+ && flags == rhs.flags
+ && reference_list == rhs.reference_list
+ && strncmp (name, rhs.name, KERNEL_MODULE_MAX_NAME) == 0
+ && 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: // MH_MAGIC
+ case llvm::MachO::HeaderMagic64: // MH_MAGIC_64
+ return lldb::endian::InlHostByteOrder();
+
+ case llvm::MachO::HeaderMagic32Swapped: // MH_CIGAM
+ case llvm::MachO::HeaderMagic64Swapped: // MH_CIGAM_64
+ 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<OSKextLoadedKextSummary> collection;
+ typedef collection::iterator iterator;
+ typedef collection::const_iterator const_iterator;
+ };
+
+ struct OSKextLoadedKextSummaryHeader
+ {
+ uint32_t version;
+ uint32_t entry_size;
+ uint32_t entry_count;
+ uint32_t reserved; /* explicit alignment for gdb */
+ lldb::addr_t image_infos_addr;
+
+ OSKextLoadedKextSummaryHeader() :
+ version (0),
+ entry_size (0),
+ entry_count (0),
+ reserved (0),
+ image_infos_addr (LLDB_INVALID_ADDRESS)
+ {
+ }
+
+ void
+ Clear()
+ {
+ version = 0;
+ entry_size = 0;
+ entry_count = 0;
+ reserved = 0;
+ image_infos_addr = LLDB_INVALID_ADDRESS;
+ }
+
+ bool
+ IsValid() const
+ {
+ return version >= 1 || version <= 2;
+ }
+ };
+
+ void
+ RegisterNotificationCallbacks();
+
+ void
+ UnregisterNotificationCallbacks();
+
+ uint32_t
+ ParseLoadCommands (const lldb_private::DataExtractor& data,
+ OSKextLoadedKextSummary& dylib_info);
+
+ bool
+ UpdateImageLoadAddress(OSKextLoadedKextSummary& info);
+
+ bool
+ FindTargetModule (OSKextLoadedKextSummary &image_info,
+ bool can_create,
+ bool *did_create_ptr);
+
+ bool
+ SetNotificationBreakpoint ();
+
+ bool
+ ReadAllKextSummaries (bool force);
+
+ bool
+ ReadKextSummaryHeader ();
+
+ bool
+ ParseKextSummaries (lldb::addr_t kext_summary_addr, uint32_t count);
+
+ bool
+ AddModulesUsingImageInfos (OSKextLoadedKextSummary::collection &image_infos);
+
+ bool
+ RemoveModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count);
+
+ void
+ UpdateImageInfosHeaderAndLoadCommands(OSKextLoadedKextSummary::collection &image_infos,
+ uint32_t infos_count,
+ bool update_executable);
+
+ bool
+ UpdateCommPageLoadAddress (lldb_private::Module *module);
+
+ uint32_t
+ ReadKextSummaries (lldb::addr_t image_infos_addr,
+ uint32_t image_infos_count,
+ OSKextLoadedKextSummary::collection &image_infos);
+
+ bool
+ UnloadImageLoadAddress (OSKextLoadedKextSummary& info);
+
+ OSKextLoadedKextSummary m_kernel; // Info about the current kernel image being used
+ lldb::addr_t m_kext_summary_header_addr;
+ OSKextLoadedKextSummaryHeader m_kext_summary_header;
+ uint32_t m_kext_summary_header_stop_id; // The process stop ID that "m_kext_summary_header" is valid for
+ lldb::user_id_t m_break_id;
+ OSKextLoadedKextSummary::collection m_kext_summaries;
+ uint32_t m_kext_summaries_stop_id; // The process stop ID that "m_kext_summaries" is valid for
+ mutable lldb_private::Mutex m_mutex;
+ lldb_private::Process::Notifications m_notification_callbacks;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN (DynamicLoaderMacOSXKernel);
+};
+
+#endif // liblldb_DynamicLoaderMacOSXKernel_h_
OpenPOWER on IntegriCloud