vbox的更動 49044 路徑 trunk/src/VBox/Debugger
- 時間撮記:
- 2013-10-11 上午01:06:28 (11 年 以前)
- 位置:
- trunk/src/VBox/Debugger
- 檔案:
-
- 修改 3 筆資料
- 複製 1 筆資料
圖例:
- 未更動
- 新增
- 刪除
-
trunk/src/VBox/Debugger/DBGPlugInDarwin.cpp
r48854 r49044 1 1 /* $Id$ */ 2 2 /** @file 3 * DBGPlugIn Linux - Debugger and Guest OS Digger Plugin For Linux.3 * DBGPlugInDarwin - Debugger and Guest OS Digger Plugin For Darwin / OS X. 4 4 */ 5 5 … … 22 22 #define LOG_GROUP LOG_GROUP_DBGF ///@todo add new log group. 23 23 #include "DBGPlugIns.h" 24 #include "DBGPlugInCommonELF.h"25 24 #include <VBox/vmm/dbgf.h> 26 25 #include <iprt/string.h> 27 26 #include <iprt/mem.h> 28 27 #include <iprt/stream.h> 28 #include <iprt/uuid.h> 29 29 #include <iprt/ctype.h> 30 #include <iprt/formats/mach-o.h> 30 31 31 32 … … 34 35 *******************************************************************************/ 35 36 36 /** @name Internal Linuxstructures37 /** @name Internal Darwin structures 37 38 * @{ */ 38 39 … … 44 45 * Linux guest OS digger instance data. 45 46 */ 46 typedef struct DBGDIGGER LINUX47 typedef struct DBGDIGGERDARWIN 47 48 { 48 49 /** Whether the information is valid or not. … … 50 51 bool fValid; 51 52 52 /** The address of the linux banner.53 /** The address of an kernel version string (there are several). 53 54 * This is set during probing. */ 54 DBGFADDRESS Addr LinuxBanner;55 DBGFADDRESS AddrKernelVersion; 55 56 /** Kernel base address. 56 57 * This is set during probing. */ 57 DBGFADDRESS AddrKernel Base;58 } DBGDIGGER LINUX;58 DBGFADDRESS AddrKernel; 59 } DBGDIGGERDARWIN; 59 60 /** Pointer to the linux guest OS digger instance data. */ 60 typedef DBGDIGGER LINUX *PDBGDIGGERLINUX;61 typedef DBGDIGGERDARWIN *PDBGDIGGERDARWIN; 61 62 62 63 … … 65 66 *******************************************************************************/ 66 67 /** Validates a 32-bit linux kernel address */ 67 #define LNX32_VALID_ADDRESS(Addr)((Addr) > UINT32_C(0x80000000) && (Addr) < UINT32_C(0xfffff000))68 #define DARWIN32_VALID_ADDRESS(Addr) ((Addr) > UINT32_C(0x80000000) && (Addr) < UINT32_C(0xfffff000)) 68 69 69 70 /** The max kernel size. */ 70 #define LNX_MAX_KERNEL_SIZE 0x0f000000 71 #define DARWIN_MAX_KERNEL_SIZE 0x0f000000 72 73 /** AppleOsX on little endian ASCII systems. */ 74 #define DIG_DARWIN_MOD_TAG UINT64_C(0x58734f656c707041) 71 75 72 76 … … 74 78 * Internal Functions * 75 79 *******************************************************************************/ 76 static DECLCALLBACK(int) dbgDigger LinuxInit(PUVM pUVM, void *pvData);80 static DECLCALLBACK(int) dbgDiggerDarwinInit(PUVM pUVM, void *pvData); 77 81 78 82 … … 92 96 * @copydoc DBGFOSREG::pfnQueryInterface 93 97 */ 94 static DECLCALLBACK(void *) dbgDigger LinuxQueryInterface(PUVM pUVM, void *pvData, DBGFOSINTERFACE enmIf)98 static DECLCALLBACK(void *) dbgDiggerDarwinQueryInterface(PUVM pUVM, void *pvData, DBGFOSINTERFACE enmIf) 95 99 { 96 100 return NULL; … … 101 105 * @copydoc DBGFOSREG::pfnQueryVersion 102 106 */ 103 static DECLCALLBACK(int) dbgDigger LinuxQueryVersion(PUVM pUVM, void *pvData, char *pszVersion, size_t cchVersion)104 { 105 PDBGDIGGER LINUX pThis = (PDBGDIGGERLINUX)pvData;107 static DECLCALLBACK(int) dbgDiggerDarwinQueryVersion(PUVM pUVM, void *pvData, char *pszVersion, size_t cchVersion) 108 { 109 PDBGDIGGERDARWIN pThis = (PDBGDIGGERDARWIN)pvData; 106 110 Assert(pThis->fValid); 107 111 … … 109 113 * It's all in the linux banner. 110 114 */ 111 int rc = DBGFR3MemReadString(pUVM, 0, &pThis->Addr LinuxBanner, pszVersion, cchVersion);115 int rc = DBGFR3MemReadString(pUVM, 0, &pThis->AddrKernelVersion, pszVersion, cchVersion); 112 116 if (RT_SUCCESS(rc)) 113 117 { … … 129 133 * @copydoc DBGFOSREG::pfnTerm 130 134 */ 131 static DECLCALLBACK(void) dbgDiggerLinuxTerm(PUVM pUVM, void *pvData) 132 { 133 PDBGDIGGERLINUX pThis = (PDBGDIGGERLINUX)pvData; 134 Assert(pThis->fValid); 135 static DECLCALLBACK(void) dbgDiggerDarwinTerm(PUVM pUVM, void *pvData) 136 { 137 PDBGDIGGERDARWIN pThis = (PDBGDIGGERDARWIN)pvData; 135 138 136 139 pThis->fValid = false; … … 141 144 * @copydoc DBGFOSREG::pfnRefresh 142 145 */ 143 static DECLCALLBACK(int) dbgDigger LinuxRefresh(PUVM pUVM, void *pvData)144 { 145 PDBGDIGGER LINUX pThis = (PDBGDIGGERLINUX)pvData;146 static DECLCALLBACK(int) dbgDiggerDarwinRefresh(PUVM pUVM, void *pvData) 147 { 148 PDBGDIGGERDARWIN pThis = (PDBGDIGGERDARWIN)pvData; 146 149 NOREF(pThis); 147 150 Assert(pThis->fValid); … … 150 153 * For now we'll flush and reload everything. 151 154 */ 152 dbgDiggerLinuxTerm(pUVM, pvData); 153 return dbgDiggerLinuxInit(pUVM, pvData); 154 } 155 155 dbgDiggerDarwinTerm(pUVM, pvData); 156 return dbgDiggerDarwinInit(pUVM, pvData); 157 } 158 159 160 /** 161 * Helper function that validates a segment (or section) name. 162 * 163 * @returns true if valid, false if not. 164 * @param pszName The name string. 165 * @param cbName The size of the string, including terminator. 166 */ 167 static bool dbgDiggerDarwinIsValidSegOrSectName(const char *pszName, size_t cbName) 168 { 169 /* ascii chars */ 170 char ch; 171 size_t off = 0; 172 while (off < cbName && (ch = pszName[off])) 173 { 174 if (RT_C_IS_CNTRL(ch) || ch > 127) 175 return false; 176 off++; 177 } 178 179 /* Not empty nor 100% full. */ 180 if (off == 0 || off == cbName) 181 return false; 182 183 /* remainder should be zeros. */ 184 while (off < cbName) 185 { 186 if (pszName[off]) 187 return false; 188 off++; 189 } 190 191 return true; 192 } 193 194 195 static int dbgDiggerDarwinAddModule(PDBGDIGGERDARWIN pThis, PUVM pUVM, uint64_t uModAddr, const char *pszName) 196 { 197 union 198 { 199 uint8_t ab[2 * X86_PAGE_4K_SIZE]; 200 mach_header_64_t Hdr64; 201 mach_header_32_t Hdr32; 202 } uBuf; 203 204 /* Read the first page of the image. */ 205 DBGFADDRESS ModAddr; 206 int rc = DBGFR3MemRead(pUVM, 0 /*idCpu*/, DBGFR3AddrFromFlat(pUVM, &ModAddr, uModAddr), uBuf.ab, X86_PAGE_4K_SIZE); 207 if (RT_FAILURE(rc)) 208 return rc; 209 210 /* Validate the header. */ 211 AssertCompileMembersSameSizeAndOffset(mach_header_64_t, magic, mach_header_32_t, magic); 212 if ( uBuf.Hdr64.magic != IMAGE_MACHO64_SIGNATURE 213 && uBuf.Hdr32.magic != IMAGE_MACHO32_SIGNATURE) 214 return VERR_INVALID_EXE_SIGNATURE; 215 AssertCompileMembersSameSizeAndOffset(mach_header_64_t, cputype, mach_header_32_t, cputype); 216 bool f64Bit = uBuf.Hdr64.magic == IMAGE_MACHO64_SIGNATURE; 217 if (uBuf.Hdr32.cputype != (f64Bit ? CPU_TYPE_X86_64 : CPU_TYPE_I386)) 218 return VERR_LDR_ARCH_MISMATCH; 219 AssertCompileMembersSameSizeAndOffset(mach_header_64_t, filetype, mach_header_32_t, filetype); 220 if ( uBuf.Hdr32.filetype != MH_EXECUTE 221 && uBuf.Hdr32.filetype != (f64Bit ? MH_KEXT_BUNDLE : MH_OBJECT)) 222 return VERR_BAD_EXE_FORMAT; 223 AssertCompileMembersSameSizeAndOffset(mach_header_64_t, ncmds, mach_header_32_t, ncmds); 224 if (uBuf.Hdr32.ncmds > 256) 225 return VERR_BAD_EXE_FORMAT; 226 AssertCompileMembersSameSizeAndOffset(mach_header_64_t, sizeofcmds, mach_header_32_t, sizeofcmds); 227 if (uBuf.Hdr32.sizeofcmds > X86_PAGE_4K_SIZE * 2 - sizeof(mach_header_64_t)) 228 return VERR_BAD_EXE_FORMAT; 229 230 /* Do we need to read a 2nd page to get all the load commands? If so, do it. */ 231 if (uBuf.Hdr32.sizeofcmds + (f64Bit ? sizeof(mach_header_64_t) : sizeof(mach_header_32_t)) > X86_PAGE_4K_SIZE) 232 { 233 rc = DBGFR3MemRead(pUVM, 0 /*idCpu*/, DBGFR3AddrFromFlat(pUVM, &ModAddr, uModAddr + X86_PAGE_4K_SIZE), 234 &uBuf.ab[X86_PAGE_4K_SIZE], X86_PAGE_4K_SIZE); 235 if (RT_FAILURE(rc)) 236 return rc; 237 } 238 239 /* 240 * Process the load commands. 241 */ 242 RTDBGSEGMENT aSegs[12]; 243 uint32_t cSegs = 0; 244 RTUUID Uuid = RTUUID_INITIALIZE_NULL; 245 uint32_t cLeft = uBuf.Hdr32.ncmds; 246 uint32_t cbLeft = uBuf.Hdr32.sizeofcmds; 247 union 248 { 249 uint8_t const *pb; 250 load_command_t const *pGenric; 251 segment_command_32_t const *pSeg32; 252 segment_command_64_t const *pSeg64; 253 section_32_t const *pSect32; 254 section_64_t const *pSect64; 255 symtab_command_t const *pSymTab; 256 uuid_command_t const *pUuid; 257 } uLCmd; 258 uLCmd.pb = &uBuf.ab[f64Bit ? sizeof(mach_header_64_t) : sizeof(mach_header_32_t)]; 259 260 while (cLeft-- > 0) 261 { 262 uint32_t const cbCmd = uLCmd.pGenric->cmdsize; 263 if (cbCmd > cbLeft || cbCmd < sizeof(load_command_t)) 264 return VERR_BAD_EXE_FORMAT; 265 266 switch (uLCmd.pGenric->cmd) 267 { 268 case LC_SEGMENT_32: 269 if (cbCmd != sizeof(segment_command_32_t) + uLCmd.pSeg32->nsects * sizeof(section_32_t)) 270 return VERR_BAD_EXE_FORMAT; 271 if (!dbgDiggerDarwinIsValidSegOrSectName(uLCmd.pSeg32->segname, sizeof(uLCmd.pSeg32->segname))) 272 return VERR_INVALID_NAME; 273 if (!strcmp(uLCmd.pSeg32->segname, "__LINKEDIT")) 274 continue; /* This usually is discarded or not loaded at all. */ 275 if (cSegs >= RT_ELEMENTS(aSegs)) 276 return VERR_BUFFER_OVERFLOW; 277 aSegs[cSegs].Address = uLCmd.pSeg32->vmaddr; 278 aSegs[cSegs].uRva = uLCmd.pSeg32->vmaddr - uModAddr; 279 aSegs[cSegs].cb = uLCmd.pSeg32->vmsize; 280 aSegs[cSegs].fFlags = uLCmd.pSeg32->flags; /* Abusing the flags field here... */ 281 aSegs[cSegs].iSeg = cSegs; 282 AssertCompile(RTDBG_SEGMENT_NAME_LENGTH > sizeof(uLCmd.pSeg32->segname)); 283 strcpy(aSegs[cSegs].szName, uLCmd.pSeg32->segname); 284 cSegs++; 285 break; 286 287 case LC_SEGMENT_64: 288 if (cbCmd != sizeof(segment_command_64_t) + uLCmd.pSeg64->nsects * sizeof(section_64_t)) 289 return VERR_BAD_EXE_FORMAT; 290 if (!dbgDiggerDarwinIsValidSegOrSectName(uLCmd.pSeg64->segname, sizeof(uLCmd.pSeg64->segname))) 291 return VERR_INVALID_NAME; 292 if (!strcmp(uLCmd.pSeg64->segname, "__LINKEDIT")) 293 continue; /* This usually is discarded or not loaded at all. */ 294 if (cSegs >= RT_ELEMENTS(aSegs)) 295 return VERR_BUFFER_OVERFLOW; 296 aSegs[cSegs].Address = uLCmd.pSeg64->vmaddr; 297 aSegs[cSegs].uRva = uLCmd.pSeg64->vmaddr - uModAddr; 298 aSegs[cSegs].cb = uLCmd.pSeg64->vmsize; 299 aSegs[cSegs].fFlags = uLCmd.pSeg64->flags; /* Abusing the flags field here... */ 300 aSegs[cSegs].iSeg = cSegs; 301 AssertCompile(RTDBG_SEGMENT_NAME_LENGTH > sizeof(uLCmd.pSeg64->segname)); 302 strcpy(aSegs[cSegs].szName, uLCmd.pSeg64->segname); 303 cSegs++; 304 break; 305 306 case LC_UUID: 307 if (cbCmd != sizeof(uuid_command_t)) 308 return VERR_BAD_EXE_FORMAT; 309 if (RTUuidIsNull((PCRTUUID)&uLCmd.pUuid->uuid[0])) 310 return VERR_BAD_EXE_FORMAT; 311 memcpy(&Uuid, &uLCmd.pUuid->uuid[0], sizeof(uLCmd.pUuid->uuid)); 312 break; 313 314 default: 315 /* Current known max plus a lot of slack. */ 316 if (uLCmd.pGenric->cmd > LC_DYLIB_CODE_SIGN_DRS + 32) 317 return VERR_BAD_EXE_FORMAT; 318 break; 319 } 320 321 /* next */ 322 cbLeft -= cbCmd; 323 uLCmd.pb += cbCmd; 324 } 325 326 if (cbLeft != 0) 327 return VERR_BAD_EXE_FORMAT; 328 329 /* 330 * Some post processing checks. 331 */ 332 uint32_t iSeg; 333 for (iSeg = 0; iSeg < cSegs; iSeg++) 334 if (aSegs[iSeg].Address == uModAddr) 335 break; 336 if (iSeg >= cSegs) 337 return VERR_ADDRESS_CONFLICT; 338 339 /* 340 * Create a debug module. 341 */ 342 RTDBGMOD hMod; 343 rc = RTDbgModCreateFromMachOImage(&hMod, pszName, NULL, f64Bit ? RTLDRARCH_AMD64 : RTLDRARCH_X86_32, 0 /*cbImage*/, 344 cSegs, aSegs, &Uuid, DBGFR3AsGetConfig(pUVM), RTDBGMOD_F_NOT_DEFERRED); 345 346 if (RT_FAILURE(rc)) 347 { 348 /* 349 * Final fallback is a container module. 350 */ 351 rc = RTDbgModCreate(&hMod, pszName, 0, 0); 352 if (RT_FAILURE(rc)) 353 return rc; 354 355 uint64_t uRvaNext = 0; 356 for (iSeg = 0; iSeg < cSegs && RT_SUCCESS(rc); iSeg++) 357 { 358 if ( aSegs[iSeg].uRva > uRvaNext 359 && aSegs[iSeg].uRva - uRvaNext < _1M) 360 uRvaNext = aSegs[iSeg].uRva; 361 rc = RTDbgModSegmentAdd(hMod, aSegs[iSeg].uRva, aSegs[iSeg].cb, aSegs[iSeg].szName, 0, NULL); 362 if (aSegs[iSeg].cb > 0 && RT_SUCCESS(rc)) 363 { 364 char szTmp[RTDBG_SEGMENT_NAME_LENGTH + sizeof("_start")]; 365 strcat(strcpy(szTmp, aSegs[iSeg].szName), "_start"); 366 rc = RTDbgModSymbolAdd(hMod, szTmp, iSeg, 0 /*uRva*/, 0 /*cb*/, 0 /*fFlags*/, NULL); 367 } 368 uRvaNext += aSegs[iSeg].cb; 369 } 370 371 if (RT_FAILURE(rc)) 372 { 373 RTDbgModRelease(hMod); 374 return rc; 375 } 376 } 377 378 /* Tag the module. */ 379 rc = RTDbgModSetTag(hMod, DIG_DARWIN_MOD_TAG); 380 AssertRC(rc); 381 382 /* 383 * Link the module. 384 */ 385 RTDBGAS hAs = DBGFR3AsResolveAndRetain(pUVM, DBGF_AS_KERNEL); 386 if (hAs != NIL_RTDBGAS) 387 { 388 uint64_t uRvaNext = 0; 389 uint32_t cLinked = 0; 390 for (iSeg = 0; iSeg < cSegs; iSeg++) 391 if (aSegs[iSeg].cb) 392 { 393 int rc2 = RTDbgAsModuleLinkSeg(hAs, hMod, iSeg, aSegs[iSeg].Address, RTDBGASLINK_FLAGS_REPLACE /*fFlags*/); 394 if (RT_SUCCESS(rc2)) 395 cLinked++; 396 else if (RT_SUCCESS(rc)) 397 rc = rc2; 398 } 399 if (RT_FAILURE(rc) && cLinked != 0) 400 rc = -rc; 401 } 402 else 403 rc = VERR_INTERNAL_ERROR; 404 RTDbgModRelease(hMod); 405 RTDbgAsRelease(hAs); 406 407 return rc; 408 } 156 409 157 410 /** 158 411 * @copydoc DBGFOSREG::pfnInit 159 412 */ 160 static DECLCALLBACK(int) dbgDigger LinuxInit(PUVM pUVM, void *pvData)161 { 162 PDBGDIGGER LINUX pThis = (PDBGDIGGERLINUX)pvData;413 static DECLCALLBACK(int) dbgDiggerDarwinInit(PUVM pUVM, void *pvData) 414 { 415 PDBGDIGGERDARWIN pThis = (PDBGDIGGERDARWIN)pvData; 163 416 Assert(!pThis->fValid); 164 #if 0 /* later */ 165 int rc; 166 167 /* 168 * Algorithm to find the ksymtab: 169 * 1. Find a known export string in kstrtab ("init_task", "enable_hlt" or something). 170 * 2. Search for the address its at, this should give you the corresponding ksymtab entry. 171 * 3. Search backwards assuming that kstrtab is corresponding to ksymtab. 172 */ 173 DBGFADDRESS AddrKernelKsymTab; 174 175 176 #endif 177 pThis->fValid = true; 417 418 /* 419 * Add the kernel module (and later the other kernel modules we can find). 420 */ 421 int rc = dbgDiggerDarwinAddModule(pThis, pUVM, pThis->AddrKernel.FlatPtr, "mach_kernel"); 422 if (RT_SUCCESS(rc)) 423 { 424 /** @todo */ 425 pThis->fValid = true; 426 return VINF_SUCCESS; 427 } 428 429 return rc; 430 } 431 432 433 /** 434 * @copydoc DBGFOSREG::pfnProbe 435 */ 436 static DECLCALLBACK(bool) dbgDiggerDarwinProbe(PUVM pUVM, void *pvData) 437 { 438 PDBGDIGGERDARWIN pThis = (PDBGDIGGERDARWIN)pvData; 439 440 /* 441 * Look for a section + segment combo that normally only occures in 442 * mach_kernel. Follow it up with probing of the rest of the executable 443 * header. We must search a largish area because the more recent versions 444 * of darwin have random load address for security raisins. 445 */ 446 static struct { uint64_t uStart, uEnd; } const s_aRanges[] = 447 { 448 /* 64-bit: */ 449 { UINT64_C(0xffffff8000000000), UINT64_C(0xffffff81ffffffff), }, 450 451 /* 32-bit - always search for this because of the hybrid 32-bit kernel 452 with cpu in long mode that darwin used for a number of versions. */ 453 { UINT64_C(0x00001000), UINT64_C(0x0ffff000), } 454 }; 455 for (unsigned iRange = DBGFR3CpuGetMode(pUVM, 0 /*idCpu*/) != CPUMMODE_LONG; 456 iRange < RT_ELEMENTS(s_aRanges); 457 iRange++) 458 { 459 DBGFADDRESS KernelAddr; 460 for (DBGFR3AddrFromFlat(pUVM, &KernelAddr, s_aRanges[iRange].uStart); 461 KernelAddr.FlatPtr < s_aRanges[iRange].uEnd; 462 KernelAddr.FlatPtr += X86_PAGE_4K_SIZE) 463 { 464 static const uint8_t s_abNeedle[16 + 16] = 465 { 466 '_','_','t','e','x','t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* section_32_t::sectname */ 467 '_','_','K','L','D', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* section_32_t::segname. */ 468 }; 469 470 int rc = DBGFR3MemScan(pUVM, 0 /*idCpu*/, &KernelAddr, s_aRanges[iRange].uEnd - KernelAddr.FlatPtr, 471 1, s_abNeedle, sizeof(s_abNeedle), &KernelAddr); 472 if (RT_FAILURE(rc)) 473 break; 474 DBGFR3AddrSub(&KernelAddr, KernelAddr.FlatPtr & X86_PAGE_4K_OFFSET_MASK); 475 476 /* 477 * Read the first page of the image and check the headers. 478 */ 479 union 480 { 481 uint8_t ab[X86_PAGE_4K_SIZE]; 482 mach_header_64_t Hdr64; 483 mach_header_32_t Hdr32; 484 } uBuf; 485 rc = DBGFR3MemRead(pUVM, 0 /*idCpu*/, &KernelAddr, uBuf.ab, X86_PAGE_4K_SIZE); 486 if (RT_FAILURE(rc)) 487 continue; 488 AssertCompileMembersSameSizeAndOffset(mach_header_64_t, magic, mach_header_32_t, magic); 489 if ( uBuf.Hdr64.magic != IMAGE_MACHO64_SIGNATURE 490 && uBuf.Hdr32.magic != IMAGE_MACHO32_SIGNATURE) 491 continue; 492 AssertCompileMembersSameSizeAndOffset(mach_header_64_t, cputype, mach_header_32_t, cputype); 493 bool f64Bit = uBuf.Hdr64.magic == IMAGE_MACHO64_SIGNATURE; 494 if (uBuf.Hdr32.cputype != (f64Bit ? CPU_TYPE_X86_64 : CPU_TYPE_I386)) 495 continue; 496 AssertCompileMembersSameSizeAndOffset(mach_header_64_t, filetype, mach_header_32_t, filetype); 497 if (uBuf.Hdr32.filetype != MH_EXECUTE) 498 continue; 499 AssertCompileMembersSameSizeAndOffset(mach_header_64_t, ncmds, mach_header_32_t, ncmds); 500 if (uBuf.Hdr32.ncmds > 256) 501 continue; 502 AssertCompileMembersSameSizeAndOffset(mach_header_64_t, sizeofcmds, mach_header_32_t, sizeofcmds); 503 if (uBuf.Hdr32.sizeofcmds > X86_PAGE_4K_SIZE - sizeof(mach_header_64_t)) 504 continue; 505 506 /* Seems good enough for now. 507 508 If the above causes false positives, check the segments and make 509 sure there is a kernel version string in the right one. */ 510 pThis->AddrKernel = KernelAddr; 511 512 /* 513 * Finally, find the kernel version string. 514 */ 515 rc = DBGFR3MemScan(pUVM, 0 /*idCpu*/, &KernelAddr, 32*_1M, 1, RT_STR_TUPLE("Darwin Kernel Version"), 516 &pThis->AddrKernelVersion); 517 if (RT_FAILURE(rc)) 518 DBGFR3AddrFromFlat(pUVM, &pThis->AddrKernelVersion, 0); 519 return true; 520 } 521 } 522 return false; 523 } 524 525 526 /** 527 * @copydoc DBGFOSREG::pfnDestruct 528 */ 529 static DECLCALLBACK(void) dbgDiggerDarwinDestruct(PUVM pUVM, void *pvData) 530 { 531 532 } 533 534 535 /** 536 * @copydoc DBGFOSREG::pfnConstruct 537 */ 538 static DECLCALLBACK(int) dbgDiggerDarwinConstruct(PUVM pUVM, void *pvData) 539 { 178 540 return VINF_SUCCESS; 179 541 } 180 542 181 543 182 /** 183 * @copydoc DBGFOSREG::pfnProbe 184 */ 185 static DECLCALLBACK(bool) dbgDiggerLinuxProbe(PUVM pUVM, void *pvData) 186 { 187 PDBGDIGGERLINUX pThis = (PDBGDIGGERLINUX)pvData; 188 189 /* 190 * Look for "Linux version " at the start of the rodata segment. 191 * Hope that this comes before any message buffer or other similar string. 192 * . 193 * Note! Only Linux version 2.x.y, where x in {0..6}. . 194 */ 195 for (unsigned i = 0; i < RT_ELEMENTS(g_au64LnxKernelAddresses); i++) 196 { 197 DBGFADDRESS KernelAddr; 198 DBGFR3AddrFromFlat(pUVM, &KernelAddr, g_au64LnxKernelAddresses[i]); 199 DBGFADDRESS HitAddr; 200 static const uint8_t s_abLinuxVersion[] = "Linux version 2."; 201 int rc = DBGFR3MemScan(pUVM, 0, &KernelAddr, LNX_MAX_KERNEL_SIZE, 1, 202 s_abLinuxVersion, sizeof(s_abLinuxVersion) - 1, &HitAddr); 203 if (RT_SUCCESS(rc)) 204 { 205 char szTmp[128]; 206 char const *pszY = &szTmp[sizeof(s_abLinuxVersion) - 1]; 207 rc = DBGFR3MemReadString(pUVM, 0, &HitAddr, szTmp, sizeof(szTmp)); 208 if ( RT_SUCCESS(rc) 209 && *pszY >= '0' 210 && *pszY <= '6') 211 { 212 pThis->AddrKernelBase = KernelAddr; 213 pThis->AddrLinuxBanner = HitAddr; 214 return true; 215 } 216 } 217 } 218 return false; 219 } 220 221 222 /** 223 * @copydoc DBGFOSREG::pfnDestruct 224 */ 225 static DECLCALLBACK(void) dbgDiggerLinuxDestruct(PUVM pUVM, void *pvData) 226 { 227 228 } 229 230 231 /** 232 * @copydoc DBGFOSREG::pfnConstruct 233 */ 234 static DECLCALLBACK(int) dbgDiggerLinuxConstruct(PUVM pUVM, void *pvData) 235 { 236 return VINF_SUCCESS; 237 } 238 239 240 const DBGFOSREG g_DBGDiggerLinux = 544 const DBGFOSREG g_DBGDiggerDarwin = 241 545 { 242 546 /* .u32Magic = */ DBGFOSREG_MAGIC, 243 547 /* .fFlags = */ 0, 244 /* .cbData = */ sizeof(DBGDIGGER LINUX),245 /* .szName = */ " Linux",246 /* .pfnConstruct = */ dbgDigger LinuxConstruct,247 /* .pfnDestruct = */ dbgDigger LinuxDestruct,248 /* .pfnProbe = */ dbgDigger LinuxProbe,249 /* .pfnInit = */ dbgDigger LinuxInit,250 /* .pfnRefresh = */ dbgDigger LinuxRefresh,251 /* .pfnTerm = */ dbgDigger LinuxTerm,252 /* .pfnQueryVersion = */ dbgDigger LinuxQueryVersion,253 /* .pfnQueryInterface = */ dbgDigger LinuxQueryInterface,548 /* .cbData = */ sizeof(DBGDIGGERDARWIN), 549 /* .szName = */ "Darwin", 550 /* .pfnConstruct = */ dbgDiggerDarwinConstruct, 551 /* .pfnDestruct = */ dbgDiggerDarwinDestruct, 552 /* .pfnProbe = */ dbgDiggerDarwinProbe, 553 /* .pfnInit = */ dbgDiggerDarwinInit, 554 /* .pfnRefresh = */ dbgDiggerDarwinRefresh, 555 /* .pfnTerm = */ dbgDiggerDarwinTerm, 556 /* .pfnQueryVersion = */ dbgDiggerDarwinQueryVersion, 557 /* .pfnQueryInterface = */ dbgDiggerDarwinQueryInterface, 254 558 /* .u32EndMagic = */ DBGFOSREG_MAGIC 255 559 }; -
trunk/src/VBox/Debugger/DBGPlugInDiggers.cpp
r44528 r49044 32 32 static PCDBGFOSREG s_aPlugIns[] = 33 33 { 34 &g_DBGDiggerDarwin, 34 35 //&g_DBGDiggerFreeBSD, 35 36 &g_DBGDiggerLinux, -
trunk/src/VBox/Debugger/DBGPlugIns.h
r35346 r49044 8 8 9 9 /* 10 * Copyright (C) 2008-201 0Oracle Corporation10 * Copyright (C) 2008-2013 Oracle Corporation 11 11 * 12 12 * This file is part of VirtualBox Open Source Edition (OSE), as … … 26 26 RT_C_DECLS_BEGIN 27 27 28 extern const DBGFOSREG g_DBGDiggerFreeBSD; 28 //extern const DBGFOSREG g_DBGDiggerFreeBSD; 29 extern const DBGFOSREG g_DBGDiggerDarwin; 29 30 extern const DBGFOSREG g_DBGDiggerLinux; 30 31 extern const DBGFOSREG g_DBGDiggerOS2; -
trunk/src/VBox/Debugger/Makefile.kmk
r46474 r49044 61 61 DBGCPlugInDiggers_SOURCES = \ 62 62 DBGPlugInDiggers.cpp \ 63 DBGPlugInDarwin.cpp \ 63 64 DBGPlugInLinux.cpp \ 64 65 DBGPlugInSolaris.cpp \
注意:
瀏覽 TracChangeset
來幫助您使用更動檢視器