Changeset 54232 in vbox
- Timestamp:
- Feb 17, 2015 2:43:41 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Debugger/DBGPlugInDarwin.cpp
r52838 r54232 93 93 bool fValid; 94 94 95 /** Set if 64-bit kernel, clear if 32-bit. 96 * Set during probing. */ 97 bool f64Bit; 95 98 /** The address of an kernel version string (there are several). 96 99 * This is set during probing. */ … … 99 102 * This is set during probing. */ 100 103 DBGFADDRESS AddrKernel; 104 105 /** The kernel message log interface. */ 106 DBGFOSIDMESG IDmesg; 101 107 } DBGDIGGERDARWIN; 102 108 /** Pointer to the linux guest OS digger instance data. */ … … 126 132 127 133 /** 134 * @interface_method_impl{DBGFOSIDMESG,pfnQueryKernelLog} 135 */ 136 static DECLCALLBACK(int) dbgDiggerDarwinIDmsg_QueryKernelLog(PDBGFOSIDMESG pThis, PUVM pUVM, uint32_t fFlags, uint32_t cMessages, 137 char *pszBuf, size_t cbBuf, size_t *pcbActual) 138 { 139 PDBGDIGGERDARWIN pData = RT_FROM_MEMBER(pThis, DBGDIGGERDARWIN, IDmesg); 140 141 if (cMessages < 1) 142 return VERR_INVALID_PARAMETER; 143 144 /* 145 * The 'msgbufp' variable points to a struct msgbuf (bsd/kern/subr_log.c). 146 */ 147 RTDBGAS hAs = DBGFR3AsResolveAndRetain(pUVM, DBGF_AS_KERNEL); 148 RTDBGMOD hMod; 149 int rc = RTDbgAsModuleByName(hAs, "mach_kernel", 0, &hMod); 150 if (RT_FAILURE(rc)) 151 return VERR_NOT_FOUND; 152 RTDbgAsRelease(hAs); 153 154 DBGFADDRESS Addr; 155 RTGCPTR GCPtrMsgBufP = 0; 156 RTDBGSYMBOL SymInfo; 157 rc = RTDbgModSymbolByName(hMod, "_msgbufp", &SymInfo); 158 if (RT_SUCCESS(rc)) 159 { 160 rc = DBGFR3MemRead(pUVM, 0 /*idCpu*/, DBGFR3AddrFromFlat(pUVM, &Addr, SymInfo.Value + pData->AddrKernel.FlatPtr), 161 &GCPtrMsgBufP, pData->f64Bit ? sizeof(uint64_t) : sizeof(uint32_t)); 162 if (RT_FAILURE(rc)) 163 { 164 Log(("dbgDiggerDarwinIDmsg_QueryKernelLog: failed to read _msgbufp at %RGv: %Rrc\n", Addr.FlatPtr, rc)); 165 return VERR_NOT_FOUND; 166 } 167 if (!OSX_VALID_ADDRESS(pData->f64Bit, GCPtrMsgBufP)) 168 { 169 Log(("dbgDiggerDarwinIDmsg_QueryKernelLog: Invalid address for _msgbufp: %RGv\n", GCPtrMsgBufP)); 170 return VERR_NOT_FOUND; 171 } 172 } 173 else 174 { 175 rc = RTDbgModSymbolByName(hMod, "_msgbuf", &SymInfo); 176 if (RT_FAILURE(rc)) 177 { 178 Log(("dbgDiggerDarwinIDmsg_QueryKernelLog: failed to find _msgbufp and _msgbuf: %Rrc\n", rc)); 179 return VERR_NOT_FOUND; 180 } 181 GCPtrMsgBufP = SymInfo.Value + pData->AddrKernel.FlatPtr; 182 if (!OSX_VALID_ADDRESS(pData->f64Bit, GCPtrMsgBufP)) 183 { 184 Log(("dbgDiggerDarwinIDmsg_QueryKernelLog: Invalid address for _msgbuf: %RGv\n", GCPtrMsgBufP)); 185 return VERR_NOT_FOUND; 186 } 187 } 188 189 /* 190 * Read the msgbuf structure. 191 */ 192 struct 193 { 194 uint32_t msg_magic; 195 uint32_t msg_size; 196 uint32_t msg_bufx; 197 uint32_t msg_bufr; 198 uint64_t msg_bufc; /**< Size depends on windows size. */ 199 } MsgBuf; 200 rc = DBGFR3MemRead(pUVM, 0 /*idCpu*/, DBGFR3AddrFromFlat(pUVM, &Addr, GCPtrMsgBufP), 201 &GCPtrMsgBufP, sizeof(MsgBuf) - (pData->f64Bit ? 0 : sizeof(uint32_t)) ); 202 if (RT_FAILURE(rc)) 203 { 204 Log(("dbgDiggerDarwinIDmsg_QueryKernelLog: failed to read msgbuf struct at %RGv: %Rrc\n", Addr.FlatPtr, rc)); 205 return VERR_NOT_FOUND; 206 } 207 if (!pData->f64Bit) 208 MsgBuf.msg_bufc &= UINT32_MAX; 209 210 /* 211 * Validate the structure. 212 */ 213 if ( MsgBuf.msg_magic != UINT32_C(0x63061) 214 || MsgBuf.msg_size < UINT32_C(4096) 215 || MsgBuf.msg_size > 16*_1M 216 || MsgBuf.msg_bufx > MsgBuf.msg_size 217 || MsgBuf.msg_bufr > MsgBuf.msg_size 218 || !OSX_VALID_ADDRESS(pData->f64Bit, MsgBuf.msg_bufc) ) 219 { 220 Log(("dbgDiggerDarwinIDmsg_QueryKernelLog: Invalid MsgBuf data: magic=%#x size=%#x bufx=%#x bufr=%#x bufc=%RGv\n", 221 MsgBuf.msg_magic, MsgBuf.msg_size, MsgBuf.msg_bufx, MsgBuf.msg_bufr, MsgBuf.msg_bufc)); 222 return VERR_INVALID_STATE; 223 } 224 225 /* 226 * Read the buffer. 227 */ 228 char *pchMsgBuf = (char *)RTMemAlloc(MsgBuf.msg_size); 229 if (!pchMsgBuf) 230 { 231 Log(("dbgDiggerDarwinIDmsg_QueryKernelLog: Failed to allocate %#x bytes of memory for the log buffer\n", 232 MsgBuf.msg_size)); 233 return VERR_INVALID_STATE; 234 } 235 rc = DBGFR3MemRead(pUVM, 0 /*idCpu*/, DBGFR3AddrFromFlat(pUVM, &Addr, MsgBuf.msg_bufc), pchMsgBuf, MsgBuf.msg_size); 236 if (RT_SUCCESS(rc)) 237 { 238 /* 239 * Copy it out raw. 240 */ 241 uint32_t offDst = 0; 242 if (MsgBuf.msg_bufr < MsgBuf.msg_bufx) 243 { 244 /* Single chunk between the read and write offsets. */ 245 uint32_t cbToCopy = MsgBuf.msg_bufx - MsgBuf.msg_bufr; 246 if (cbToCopy < cbBuf) 247 { 248 memcpy(pszBuf, &pchMsgBuf[MsgBuf.msg_bufr], cbToCopy); 249 pszBuf[cbToCopy] = '\0'; 250 rc = VINF_SUCCESS; 251 } 252 else 253 { 254 if (cbBuf) 255 { 256 memcpy(pszBuf, &pchMsgBuf[MsgBuf.msg_bufr], cbBuf - 1); 257 pszBuf[cbBuf - 1] = '\0'; 258 } 259 rc = VERR_BUFFER_OVERFLOW; 260 } 261 offDst = cbToCopy + 1; 262 } 263 else 264 { 265 /* Two chunks, read offset to end, start to write offset. */ 266 uint32_t cbFirst = MsgBuf.msg_size - MsgBuf.msg_bufr; 267 uint32_t cbSecond = MsgBuf.msg_bufx; 268 if (cbFirst + cbSecond < cbBuf) 269 { 270 memcpy(pszBuf, &pchMsgBuf[MsgBuf.msg_bufr], cbFirst); 271 memcpy(&pszBuf[cbFirst], pchMsgBuf, cbSecond); 272 offDst = cbFirst + cbSecond; 273 pszBuf[offDst++] = '\0'; 274 rc = VINF_SUCCESS; 275 } 276 else 277 { 278 offDst = cbFirst + cbSecond + 1; 279 if (cbFirst < cbBuf) 280 { 281 memcpy(pszBuf, &pchMsgBuf[MsgBuf.msg_bufr], cbFirst); 282 memcpy(&pszBuf[cbFirst], pchMsgBuf, cbBuf - cbFirst); 283 pszBuf[cbBuf - 1] = '\0'; 284 } 285 else if (cbBuf) 286 { 287 memcpy(pszBuf, &pchMsgBuf[MsgBuf.msg_bufr], cbBuf - 1); 288 pszBuf[cbBuf - 1] = '\0'; 289 } 290 rc = VERR_BUFFER_OVERFLOW; 291 } 292 } 293 294 if (pcbActual) 295 *pcbActual = offDst; 296 } 297 else 298 Log(("dbgDiggerDarwinIDmsg_QueryKernelLog: Error reading %#x bytes at %RGv: %Rrc\n", MsgBuf.msg_size, MsgBuf.msg_bufc)); 299 RTMemFree(pchMsgBuf); 300 return rc; 301 } 302 303 304 /** 128 305 * @copydoc DBGFOSREG::pfnQueryInterface 129 306 */ 130 307 static DECLCALLBACK(void *) dbgDiggerDarwinQueryInterface(PUVM pUVM, void *pvData, DBGFOSINTERFACE enmIf) 131 308 { 132 return NULL; 309 PDBGDIGGERDARWIN pThis = (PDBGDIGGERDARWIN)pvData; 310 switch (enmIf) 311 { 312 case DBGFOSINTERFACE_DMESG: 313 return &pThis->IDmesg; 314 315 default: 316 return NULL; 317 } 133 318 } 134 319 … … 739 924 sure there is a kernel version string in the right one. */ 740 925 pThis->AddrKernel = KernelAddr; 926 pThis->f64Bit = f64Bit; 741 927 742 928 /* … … 768 954 static DECLCALLBACK(int) dbgDiggerDarwinConstruct(PUVM pUVM, void *pvData) 769 955 { 956 PDBGDIGGERDARWIN pThis = (PDBGDIGGERDARWIN)pvData; 957 958 pThis->IDmesg.u32Magic = DBGFOSIDMESG_MAGIC; 959 pThis->IDmesg.pfnQueryKernelLog = dbgDiggerDarwinIDmsg_QueryKernelLog; 960 pThis->IDmesg.u32EndMagic = DBGFOSIDMESG_MAGIC; 961 770 962 return VINF_SUCCESS; 771 963 }
Note:
See TracChangeset
for help on using the changeset viewer.