- Timestamp:
- Oct 14, 2013 1:59:59 AM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Debugger/DBGPlugInDarwin.cpp
r49061 r49075 38 38 * @{ */ 39 39 40 /** 41 * 32-bit darwin kernel module info structure (kmod_info_t). 42 */ 43 typedef struct OSX32_kmod_info 44 { 45 uint32_t next; 46 int32_t info_version; 47 uint32_t id; 48 char name[64]; 49 char version[64]; 50 int32_t reference_count; 51 uint32_t reference_list; /**< Points to kmod_reference_t. */ 52 uint32_t address; /**< Where in memory the kext is loaded. */ 53 uint32_t size; 54 uint32_t hdr_size; 55 uint32_t start; /**< Address of kmod_start_func_t. */ 56 uint32_t stop; /**< Address of kmod_stop_func_t. */ 57 } OSX32_kmod_info_t; 58 59 /** 60 * 32-bit darwin kernel module info structure (kmod_info_t). 61 */ 62 #pragma pack(1) 63 typedef struct OSX64_kmod_info 64 { 65 uint64_t next; 66 int32_t info_version; 67 uint32_t id; 68 char name[64]; 69 char version[64]; 70 int32_t reference_count; 71 uint64_t reference_list; /**< Points to kmod_reference_t. Misaligned, duh. */ 72 uint64_t address; /**< Where in memory the kext is loaded. */ 73 uint64_t size; 74 uint64_t hdr_size; 75 uint64_t start; /**< Address of kmod_start_func_t. */ 76 uint64_t stop; /**< Address of kmod_stop_func_t. */ 77 } OSX64_kmod_info_t; 78 #pragma pack() 79 80 /** The value of the info_version field. */ 81 #define OSX_KMOD_INFO_VERSION INT32_C(1) 40 82 41 83 /** @} */ … … 65 107 * Defined Constants And Macros * 66 108 *******************************************************************************/ 67 /** Validates a 32-bit linux kernel address */ 68 #define DARWIN32_VALID_ADDRESS(Addr) ((Addr) > UINT32_C(0x80000000) && (Addr) < UINT32_C(0xfffff000)) 69 70 /** The max kernel size. */ 71 #define DARWIN_MAX_KERNEL_SIZE 0x0f000000 109 /** Validates a 32-bit darwin kernel address */ 110 #define OSX32_VALID_ADDRESS(Addr) ((Addr) > UINT32_C(0x00001000) && (Addr) < UINT32_C(0xfffff000)) 111 /** Validates a 64-bit darwin kernel address */ 112 #define OSX64_VALID_ADDRESS(Addr) ((Addr) > UINT64_C(0xffff800000000000) && (Addr) < UINT32_C(0xfffffffffffff000)) 113 /** Validates a 32-bit or 64-bit darwin kernel address. */ 114 #define OSX_VALID_ADDRESS(a_f64Bits, a_Addr) \ 115 ((a_f64Bits) ? OSX64_VALID_ADDRESS(a_Addr) : OSX32_VALID_ADDRESS(a_Addr)) 72 116 73 117 /** AppleOsX on little endian ASCII systems. */ … … 79 123 *******************************************************************************/ 80 124 static DECLCALLBACK(int) dbgDiggerDarwinInit(PUVM pUVM, void *pvData); 81 82 83 /*******************************************************************************84 * Global Variables *85 *******************************************************************************/86 /** Table of common linux kernel addresses. */87 static uint64_t g_au64LnxKernelAddresses[] =88 {89 UINT64_C(0xc0100000),90 UINT64_C(0x90100000),91 UINT64_C(0xffffffff80200000)92 };93 125 94 126 … … 193 225 194 226 195 static int dbgDiggerDarwinAddModule(PDBGDIGGERDARWIN pThis, PUVM pUVM, uint64_t uModAddr, const char *pszName )227 static int dbgDiggerDarwinAddModule(PDBGDIGGERDARWIN pThis, PUVM pUVM, uint64_t uModAddr, const char *pszName, bool *pf64Bit) 196 228 { 197 229 union … … 416 448 else 417 449 rc = VERR_INTERNAL_ERROR; 450 418 451 RTDbgModRelease(hMod); 419 452 RTDbgAsRelease(hAs); 420 453 454 if (pf64Bit) 455 *pf64Bit = f64Bit; 421 456 return rc; 422 457 } 458 459 460 static bool dbgDiggerDarwinIsValidName(const char *pszName) 461 { 462 char ch; 463 while ((ch = *pszName++) != '\0') 464 { 465 if (ch < 0x20 || ch >= 127) 466 return false; 467 } 468 return true; 469 } 470 471 472 static bool dbgDiggerDarwinIsValidVersion(const char *pszVersion) 473 { 474 char ch; 475 while ((ch = *pszVersion++) != '\0') 476 { 477 if (ch < 0x20 || ch >= 127) 478 return false; 479 } 480 return true; 481 } 482 423 483 424 484 /** … … 431 491 432 492 /* 433 * Add the kernel module (and later the other kernel modules we can find).493 * Add the kernel module. 434 494 */ 435 int rc = dbgDiggerDarwinAddModule(pThis, pUVM, pThis->AddrKernel.FlatPtr, "mach_kernel"); 495 bool f64Bit; 496 int rc = dbgDiggerDarwinAddModule(pThis, pUVM, pThis->AddrKernel.FlatPtr, "mach_kernel", &f64Bit); 436 497 if (RT_SUCCESS(rc)) 437 498 { 438 /** @todo */ 499 /* 500 * The list of modules can be found at the 'kmod' symbol, that means 501 * that we currently require some kind of symbol file for the kernel 502 * to be loaded at this point. 503 * 504 * Note! Could also use the 'gLoadedKextSummaries', but I don't think 505 * it's any easier to find without any kernel map than 'kmod'. 506 */ 507 RTDBGSYMBOL SymInfo; 508 rc = DBGFR3AsSymbolByName(pUVM, DBGF_AS_KERNEL, "mach_kernel!kmod", &SymInfo, NULL); 509 if (RT_FAILURE(rc)) 510 rc = DBGFR3AsSymbolByName(pUVM, DBGF_AS_KERNEL, "mach_kernel!_kmod", &SymInfo, NULL); 511 if (RT_SUCCESS(rc)) 512 { 513 DBGFADDRESS AddrModInfo; 514 DBGFR3AddrFromFlat(pUVM, &AddrModInfo, SymInfo.Value); 515 516 /* Read the variable. */ 517 RTUINT64U uKmodValue = { 0 }; 518 if (f64Bit) 519 rc = DBGFR3MemRead(pUVM, 0 /*idCpu*/, &AddrModInfo, &uKmodValue.u, sizeof(uKmodValue.u)); 520 else 521 rc = DBGFR3MemRead (pUVM, 0 /*idCpu*/, &AddrModInfo, &uKmodValue.s.Lo, sizeof(uKmodValue.s.Lo)); 522 if (RT_SUCCESS(rc)) 523 { 524 DBGFR3AddrFromFlat(pUVM, &AddrModInfo, uKmodValue.u); 525 526 /* Walk the list of modules. */ 527 uint32_t cIterations = 0; 528 while (AddrModInfo.FlatPtr != 0) 529 { 530 /* Some extra loop conditions... */ 531 if (!OSX_VALID_ADDRESS(f64Bit, AddrModInfo.FlatPtr)) 532 { 533 Log(("OSXDig: Invalid kmod_info pointer: %RGv\n", AddrModInfo.FlatPtr)); 534 break; 535 } 536 if (AddrModInfo.FlatPtr == uKmodValue.u && cIterations != 0) 537 { 538 Log(("OSXDig: kmod_info list looped back to the start.\n")); 539 break; 540 } 541 if (cIterations++ >= 2048) 542 { 543 Log(("OSXDig: Too many mod_info loops (%u)\n", cIterations)); 544 break; 545 } 546 547 /* 548 * Read the kmod_info_t structure. 549 */ 550 union 551 { 552 OSX64_kmod_info_t Info64; 553 OSX32_kmod_info_t Info32; 554 } uMod; 555 RT_ZERO(uMod); 556 rc = DBGFR3MemRead(pUVM, 0 /*idCpu*/, &AddrModInfo, &uMod, 557 f64Bit ? sizeof(uMod.Info64) : sizeof(uMod.Info64)); 558 if (RT_FAILURE(rc)) 559 { 560 Log(("OSXDig: Error reading kmod_info structure at %RGv: %Rrc\n", AddrModInfo.FlatPtr, rc)); 561 break; 562 } 563 564 /* 565 * Validate the kmod_info_t structure. 566 */ 567 int32_t iInfoVer = f64Bit ? uMod.Info64.info_version : uMod.Info32.info_version; 568 if (iInfoVer != OSX_KMOD_INFO_VERSION) 569 { 570 Log(("OSXDig: kmod_info @%RGv: Bad info_version %d\n", AddrModInfo.FlatPtr, iInfoVer)); 571 break; 572 } 573 574 const char *pszName = f64Bit ? uMod.Info64.name : uMod.Info32.name; 575 if ( !*pszName 576 || !RTStrEnd(pszName, sizeof(uMod.Info64.name)) 577 || !dbgDiggerDarwinIsValidName(pszName) ) 578 { 579 Log(("OSXDig: kmod_info @%RGv: Bad name '%.*s'\n", AddrModInfo.FlatPtr, 580 sizeof(uMod.Info64.name), pszName)); 581 break; 582 } 583 584 const char *pszVersion = f64Bit ? uMod.Info64.version : uMod.Info32.version; 585 if ( !RTStrEnd(pszVersion, sizeof(uMod.Info64.version)) 586 || !dbgDiggerDarwinIsValidVersion(pszVersion) ) 587 { 588 Log(("OSXDig: kmod_info @%RGv: Bad version '%.*s'\n", AddrModInfo.FlatPtr, 589 sizeof(uMod.Info64.version), pszVersion)); 590 break; 591 } 592 593 int32_t cRefs = f64Bit ? uMod.Info64.reference_count : uMod.Info32.reference_count; 594 if (cRefs < -1 || cRefs > 16384) 595 { 596 Log(("OSXDig: kmod_info @%RGv: Bad reference_count %d\n", AddrModInfo.FlatPtr, cRefs)); 597 break; 598 } 599 600 uint64_t uImageAddr = f64Bit ? uMod.Info64.address : uMod.Info32.address; 601 if (!OSX_VALID_ADDRESS(f64Bit, uImageAddr)) 602 { 603 Log(("OSXDig: kmod_info @%RGv: Bad address %#llx\n", AddrModInfo.FlatPtr, uImageAddr)); 604 break; 605 } 606 607 uint64_t cbImage = f64Bit ? uMod.Info64.size : uMod.Info32.size; 608 if (cbImage > 64U*_1M) 609 { 610 Log(("OSXDig: kmod_info @%RGv: Bad size %#llx\n", AddrModInfo.FlatPtr, cbImage)); 611 break; 612 } 613 614 uint64_t cbHdr = f64Bit ? uMod.Info64.hdr_size : uMod.Info32.hdr_size; 615 if (cbHdr > 16U*_1M) 616 { 617 Log(("OSXDig: kmod_info @%RGv: Bad hdr_size %#llx\n", AddrModInfo.FlatPtr, cbHdr)); 618 break; 619 } 620 621 uint64_t uStartAddr = f64Bit ? uMod.Info64.start : uMod.Info32.start; 622 if (!uStartAddr && !OSX_VALID_ADDRESS(f64Bit, uStartAddr)) 623 { 624 Log(("OSXDig: kmod_info @%RGv: Bad start function %#llx\n", AddrModInfo.FlatPtr, uStartAddr)); 625 break; 626 } 627 628 uint64_t uStopAddr = f64Bit ? uMod.Info64.stop : uMod.Info32.stop; 629 if (!uStopAddr && !OSX_VALID_ADDRESS(f64Bit, uStopAddr)) 630 { 631 Log(("OSXDig: kmod_info @%RGv: Bad stop function %#llx\n", AddrModInfo.FlatPtr, uStopAddr)); 632 break; 633 } 634 635 /* 636 * Try add the module. 637 */ 638 Log(("OSXDig: kmod_info @%RGv: '%s' ver '%s', image @%#llx LB %#llx cbHdr=%#llx\n", 639 pszName, pszVersion, uImageAddr, cbImage, cbHdr)); 640 rc = dbgDiggerDarwinAddModule(pThis, pUVM, uImageAddr, pszName, NULL); 641 642 643 /* 644 * Advance to the next kmod_info entry. 645 */ 646 DBGFR3AddrFromFlat(pUVM, &AddrModInfo, f64Bit ? uMod.Info64.next : uMod.Info32.next); 647 } 648 } 649 else 650 Log(("OSXDig: Error reading the 'kmod' variable: %Rrc\n", rc)); 651 } 652 else 653 Log(("OSXDig: Failed to locate the 'kmod' variable in mach_kernel.\n")); 654 439 655 pThis->fValid = true; 440 656 return VINF_SUCCESS;
Note:
See TracChangeset
for help on using the changeset viewer.