| Chris Lattner | 30fdc8d | 2010-06-08 16:52:24 +0000 | [diff] [blame] | 1 | //===-- MachDYLD.h ----------------------------------------------*- 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 | // Created by Greg Clayton on 6/29/07. |
| 11 | // |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
| 14 | #ifndef __MachDYLD_h__ |
| 15 | #define __MachDYLD_h__ |
| 16 | |
| 17 | #include "DNBDefs.h" |
| 18 | #include "DNBRuntimeAction.h" |
| 19 | #include "PThreadMutex.h" |
| 20 | #include <map> |
| 21 | #include <vector> |
| 22 | #include <string> |
| 23 | |
| 24 | class DNBBreakpoint; |
| 25 | class MachProcess; |
| 26 | |
| 27 | class MachDYLD : public DNBRuntimeAction |
| 28 | { |
| 29 | public: |
| 30 | MachDYLD (); |
| 31 | virtual ~MachDYLD (); |
| 32 | |
| 33 | //------------------------------------------------------------------ |
| 34 | // DNBRuntimeAction required functions |
| 35 | //------------------------------------------------------------------ |
| 36 | virtual void Initialize(nub_process_t pid); |
| 37 | virtual void ProcessStateChanged(nub_state_t state); |
| 38 | virtual void SharedLibraryStateChanged(DNBExecutableImageInfo *image_infos, nub_size_t num_image_infos); |
| 39 | |
| 40 | protected: |
| 41 | bool CheckForDYLDInMemory(); |
| 42 | bool FoundDYLD() const; |
| 43 | void Clear(); |
| 44 | void Dump(FILE *f) const; |
| 45 | nub_process_t ProcessID() const { return m_pid; } |
| 46 | uint32_t AddrByteSize() const { return m_addr_size; } |
| 47 | nub_size_t CopyCurrentShlibInfo(DNBExecutableImageInfo **image_infos); |
| 48 | nub_size_t CopyChangedShlibInfo(DNBExecutableImageInfo **image_infos); |
| 49 | nub_addr_t GetSharedLibraryHeaderAddress(const char *shlib_path) const; |
| 50 | bool CheckForDYLDInMemory(nub_addr_t addr); |
| 51 | bool ReadDYLIBInfo (); |
| 52 | static nub_bool_t BreakpointHit (nub_process_t pid, nub_thread_t tid, nub_break_t breakID, void *baton); |
| 53 | void UpdateUUIDs(); |
| 54 | |
| 55 | struct DYLIBInfo |
| 56 | { |
| 57 | nub_addr_t address; // Address of mach header for this dylib |
| 58 | nub_addr_t mod_date; // Modification date for this dylib |
| 59 | std::string path; // Resolved path for this dylib |
| 60 | uint8_t uuid[16]; // UUID for this dylib if it has one, else all zeros |
| 61 | std::vector<DNBSegment> segments; // All segment vmaddr and vmsize pairs for this executable (from memory of inferior) |
| 62 | |
| 63 | DYLIBInfo() : |
| 64 | address(INVALID_NUB_ADDRESS), |
| 65 | mod_date(0), |
| 66 | path(), |
| 67 | segments() |
| 68 | { |
| 69 | memset(uuid, 0, 16); |
| 70 | } |
| 71 | |
| 72 | void Clear() |
| 73 | { |
| 74 | address = INVALID_NUB_ADDRESS; |
| 75 | mod_date = 0; |
| 76 | path.clear(); |
| 77 | segments.clear(); |
| 78 | memset(uuid, 0, 16); |
| 79 | } |
| 80 | |
| 81 | bool operator == (const DYLIBInfo& rhs) const |
| 82 | { |
| 83 | return address == rhs.address |
| 84 | && mod_date == rhs.mod_date |
| 85 | && path == rhs.path |
| 86 | && memcmp(uuid, rhs.uuid, 16) == 0; |
| 87 | } |
| 88 | bool UUIDValid() const |
| 89 | { |
| 90 | return uuid[ 0] || uuid[ 1] || uuid[ 2] || uuid[ 3] || |
| 91 | uuid[ 4] || uuid[ 5] || uuid[ 6] || uuid[ 7] || |
| 92 | uuid[ 8] || uuid[ 9] || uuid[10] || uuid[11] || |
| 93 | uuid[12] || uuid[13] || uuid[14] || uuid[15]; |
| 94 | } |
| 95 | |
| 96 | void Dump(FILE *f) const; |
| 97 | typedef std::vector<DYLIBInfo> collection; |
| 98 | typedef collection::iterator iterator; |
| 99 | typedef collection::const_iterator const_iterator; |
| 100 | }; |
| 101 | struct InfoHeader |
| 102 | { |
| 103 | uint32_t version; /* == 1 in Mac OS X 10.4, == 2 in Mac OS 10.5 */ |
| 104 | uint32_t dylib_info_count; |
| 105 | nub_addr_t dylib_info_addr; |
| 106 | nub_addr_t notification; |
| 107 | bool processDetachedFromSharedRegion; |
| 108 | |
| 109 | InfoHeader() : |
| 110 | version(0), |
| 111 | dylib_info_count(0), |
| 112 | dylib_info_addr(INVALID_NUB_ADDRESS), |
| 113 | notification(INVALID_NUB_ADDRESS), |
| 114 | processDetachedFromSharedRegion(false) |
| 115 | { |
| 116 | } |
| 117 | |
| 118 | void Clear() |
| 119 | { |
| 120 | version = 0; |
| 121 | dylib_info_count = 0; |
| 122 | dylib_info_addr = INVALID_NUB_ADDRESS; |
| 123 | notification = INVALID_NUB_ADDRESS; |
| 124 | processDetachedFromSharedRegion = false; |
| 125 | } |
| 126 | |
| 127 | bool IsValid() const |
| 128 | { |
| 129 | return version == 1 || version == 2; |
| 130 | } |
| 131 | }; |
| 132 | static nub_size_t CopySharedLibraryInfo(DYLIBInfo::collection& dylib_coll, DNBExecutableImageInfo **image_infos); |
| 133 | static nub_size_t CopySharedInfoCallback(nub_process_t pid, struct DNBExecutableImageInfo **image_infos, nub_bool_t only_changed, void *baton); |
| 134 | nub_process_t m_pid; |
| 135 | uint32_t m_addr_size; |
| 136 | nub_addr_t m_dyld_addr; |
| 137 | nub_addr_t m_dyld_all_image_infos_addr; |
| 138 | InfoHeader m_dylib_info_header; |
| 139 | DYLIBInfo::collection m_current_dylibs; // Current shared libraries information |
| 140 | DYLIBInfo::collection m_changed_dylibs; // Shared libraries that changed since last shared library update |
| 141 | nub_break_t m_notify_break_id; |
| 142 | mutable PThreadMutex m_dyld_info_mutex; |
| 143 | }; |
| 144 | |
| 145 | #endif // #ifndef __MachDYLD_h__ |