- Timestamp:
- Oct 11, 2013 1:06:28 AM (11 years ago)
- Location:
- trunk/src
- Files:
-
- 1 added
- 17 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
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 \ -
trunk/src/VBox/Runtime/common/dbg/dbgcfg.cpp
r46161 r49044 1425 1425 int rc2; 1426 1426 1427 //RTStrPrintf(szFile, sizeof(szFile), "%s.dSYM/Contents/Resources/DWARF/%s", pszFilename, pszFilename);1428 1429 1427 /* 1430 1428 * Do a little validating first. … … 1543 1541 rcRet = VERR_NOT_FOUND; 1544 1542 return rcRet; 1545 1546 1547 1543 } 1548 1544 -
trunk/src/VBox/Runtime/common/dbg/dbgmod.cpp
r49040 r49044 47 47 #include <iprt/strcache.h> 48 48 #include <iprt/string.h> 49 #include <iprt/uuid.h> 49 50 #include "internal/dbgmod.h" 50 51 #include "internal/magics.h" … … 326 327 AssertPtrReturn(pszName, VERR_INVALID_POINTER); 327 328 AssertReturn(*pszName, VERR_INVALID_PARAMETER); 328 AssertReturn(fFlags == 0 , VERR_INVALID_PARAMETER);329 AssertReturn(fFlags == 0 || fFlags == RTDBGMOD_F_NOT_DEFERRED, VERR_INVALID_PARAMETER); 329 330 330 331 int rc = rtDbgModLazyInit(); … … 1135 1136 { 1136 1137 PRTDBGMODDEFERRED pDeferred; 1137 rc = rtDbgModDeferredCreate(pDbgMod, rtDbgModFromPeImageDeferredCallback, cbImage, hDbgCfg, &pDeferred); 1138 rc = rtDbgModDeferredCreate(pDbgMod, rtDbgModFromPeImageDeferredCallback, cbImage, hDbgCfg, 0, 1139 &pDeferred); 1138 1140 if (RT_SUCCESS(rc)) 1139 1141 pDeferred->u.PeImage.uTimestamp = uTimestamp; … … 1170 1172 1171 1173 1174 1175 1176 /* 1177 * 1178 * M a c h - O I M A G E 1179 * M a c h - O I M A G E 1180 * M a c h - O I M A G E 1181 * 1182 */ 1183 1184 /** @callback_method_impl{FNRTDBGCFGOPEN} */ 1185 static DECLCALLBACK(int) 1186 rtDbgModFromMachOImageOpenMachOCallback(RTDBGCFG hDbgCfg, const char *pszFilename, void *pvUser1, void *pvUser2) 1187 { 1188 PRTDBGMODINT pDbgMod = (PRTDBGMODINT)pvUser1; 1189 PCRTDBGDWARFSEGPKG pSegPkg = (PCRTDBGDWARFSEGPKG)pvUser2; 1190 1191 /** @todo */ 1192 1193 return VERR_OPEN_FAILED; 1194 } 1195 1196 1197 /** @callback_method_impl{FNRTDBGCFGOPEN} */ 1198 static DECLCALLBACK(int) 1199 rtDbgModFromMachOImageOpenDsymCallback(RTDBGCFG hDbgCfg, const char *pszFilename, void *pvUser1, void *pvUser2) 1200 { 1201 PRTDBGMODINT pDbgMod = (PRTDBGMODINT)pvUser1; 1202 PCRTDBGDWARFSEGPKG pSegPkg = (PCRTDBGDWARFSEGPKG)pvUser2; 1203 1204 Assert(!pDbgMod->pDbgVt); 1205 Assert(!pDbgMod->pvDbgPriv); 1206 Assert(!pDbgMod->pszDbgFile); 1207 Assert(!pDbgMod->pImgVt); 1208 Assert(!pDbgMod->pvDbgPriv); 1209 Assert(pDbgMod->pszImgFile); 1210 Assert(pDbgMod->pszImgFileSpecified); 1211 1212 const char *pszImgFileOrg = pDbgMod->pszImgFile; 1213 pDbgMod->pszImgFile = RTStrCacheEnter(g_hDbgModStrCache, pszFilename); 1214 if (!pDbgMod->pszImgFile) 1215 return VERR_NO_STR_MEMORY; 1216 RTStrCacheRetain(pDbgMod->pszImgFile); 1217 pDbgMod->pszDbgFile = pDbgMod->pszImgFile; 1218 1219 /* 1220 * Try image interpreters as the dwarf file inside the dSYM bundle is a 1221 * Mach-O file with dwarf debug sections insides it and no code or data. 1222 */ 1223 int rc = RTSemRWRequestRead(g_hDbgModRWSem, RT_INDEFINITE_WAIT); 1224 if (RT_SUCCESS(rc)) 1225 { 1226 rc = VERR_DBG_NO_MATCHING_INTERPRETER; 1227 PRTDBGMODREGIMG pImg; 1228 for (pImg = g_pImgHead; pImg; pImg = pImg->pNext) 1229 { 1230 pDbgMod->pImgVt = pImg->pVt; 1231 pDbgMod->pvImgPriv = NULL; 1232 rc = pImg->pVt->pfnTryOpen(pDbgMod, pSegPkg->enmArch); 1233 if (RT_SUCCESS(rc)) 1234 break; 1235 pDbgMod->pImgVt = NULL; 1236 Assert(pDbgMod->pvImgPriv == NULL); 1237 } 1238 1239 if (RT_SUCCESS(rc)) 1240 { 1241 /* 1242 * Check the UUID if one was given. 1243 */ 1244 if (pSegPkg->pUuid) 1245 { 1246 RTUUID UuidOpened; 1247 rc = pDbgMod->pImgVt->pfnQueryProp(pDbgMod, RTLDRPROP_UUID, &UuidOpened, sizeof(UuidOpened)); 1248 if (RT_SUCCESS(rc)) 1249 { 1250 if (RTUuidCompare(&UuidOpened, pSegPkg->pUuid) != 0) 1251 rc = VERR_DBG_FILE_MISMATCH; 1252 } 1253 else if (rc == VERR_NOT_FOUND || rc == VERR_NOT_IMPLEMENTED) 1254 rc = VERR_DBG_FILE_MISMATCH; 1255 } 1256 if (RT_SUCCESS(rc)) 1257 { 1258 /* 1259 * Pass it to the DWARF reader(s). 1260 */ 1261 for (PRTDBGMODREGDBG pDbg = g_pDbgHead; pDbg; pDbg = pDbg->pNext) 1262 { 1263 if (pDbg->pVt->fSupports & RT_DBGTYPE_DWARF) 1264 { 1265 pDbgMod->pDbgVt = pDbg->pVt; 1266 pDbgMod->pvDbgPriv = pSegPkg->cSegs ? (void *)pSegPkg : NULL; 1267 rc = pDbg->pVt->pfnTryOpen(pDbgMod, pDbgMod->pImgVt->pfnGetArch(pDbgMod)); 1268 if (RT_SUCCESS(rc)) 1269 { 1270 /* 1271 * Got it! 1272 */ 1273 ASMAtomicIncU32(&pDbg->cUsers); 1274 RTSemRWReleaseRead(g_hDbgModRWSem); 1275 RTStrCacheRelease(g_hDbgModStrCache, pszImgFileOrg); 1276 return VINF_CALLBACK_RETURN; 1277 } 1278 pDbgMod->pDbgVt = NULL; 1279 Assert(pDbgMod->pvDbgPriv == NULL); 1280 } 1281 } 1282 } 1283 1284 pDbgMod->pImgVt->pfnClose(pDbgMod); 1285 pDbgMod->pImgVt = NULL; 1286 pDbgMod->pvImgPriv = NULL; 1287 } 1288 } 1289 1290 /* No joy. */ 1291 RTSemRWReleaseRead(g_hDbgModRWSem); 1292 RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFile); 1293 pDbgMod->pszImgFile = pszImgFileOrg; 1294 RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszDbgFile); 1295 pDbgMod->pszDbgFile = NULL; 1296 return rc; 1297 } 1298 1299 1300 static int rtDbgModFromMachOImageWorker(PRTDBGMODINT pDbgMod, RTLDRARCH enmArch, uint32_t cbImage, 1301 uint32_t cSegs, PCRTDBGSEGMENT paSegs, PCRTUUID pUuid, RTDBGCFG hDbgCfg) 1302 { 1303 RTDBGDWARFSEGPKG SegPkg; 1304 SegPkg.cSegs = cSegs; 1305 SegPkg.paSegs = paSegs; 1306 SegPkg.enmArch = enmArch; 1307 SegPkg.pUuid = pUuid && RTUuidIsNull(pUuid) ? pUuid : NULL; 1308 1309 /* 1310 * Search for the .dSYM bundle first, since that's generally all we need. 1311 */ 1312 int rc = RTDbgCfgOpenDsymBundle(hDbgCfg, pDbgMod->pszImgFile, pUuid, 1313 rtDbgModFromMachOImageOpenDsymCallback, pDbgMod, &SegPkg); 1314 if (RT_FAILURE(rc)) 1315 { 1316 /* 1317 * If we cannot get at the .dSYM, try the executable image. 1318 */ 1319 //rc = RTDbgCfgOpenMachOImage(hDbgCfg, pDbgMod->pszImgFile, pUuid, 1320 // rtDbgModFromMachOImageOpenMachOCallback, pDbgMod, &SegPkg); 1321 } 1322 return rc; 1323 } 1324 1325 1326 /** @callback_method_impl{FNRTDBGMODDEFERRED} */ 1327 static DECLCALLBACK(int) rtDbgModFromMachOImageDeferredCallback(PRTDBGMODINT pDbgMod, PRTDBGMODDEFERRED pDeferred) 1328 { 1329 return rtDbgModFromMachOImageWorker(pDbgMod, pDeferred->u.MachO.enmArch, pDeferred->cbImage, 1330 pDeferred->u.MachO.cSegs, pDeferred->u.MachO.aSegs, 1331 &pDeferred->u.MachO.Uuid, pDeferred->hDbgCfg); 1332 } 1333 1334 1335 RTDECL(int) RTDbgModCreateFromMachOImage(PRTDBGMOD phDbgMod, const char *pszFilename, const char *pszName, 1336 RTLDRARCH enmArch, uint32_t cbImage, uint32_t cSegs, PCRTDBGSEGMENT paSegs, 1337 PCRTUUID pUuid, RTDBGCFG hDbgCfg, uint32_t fFlags) 1338 { 1339 /* 1340 * Input validation and lazy initialization. 1341 */ 1342 AssertPtrReturn(phDbgMod, VERR_INVALID_POINTER); 1343 *phDbgMod = NIL_RTDBGMOD; 1344 AssertPtrReturn(pszFilename, VERR_INVALID_POINTER); 1345 AssertReturn(*pszFilename, VERR_INVALID_PARAMETER); 1346 if (!pszName) 1347 pszName = RTPathFilenameEx(pszFilename, RTPATH_STR_F_STYLE_HOST); 1348 AssertPtrReturn(pszName, VERR_INVALID_POINTER); 1349 if (cSegs) 1350 { 1351 AssertReturn(cSegs < 1024, VERR_INVALID_PARAMETER); 1352 AssertPtrReturn(paSegs, VERR_INVALID_POINTER); 1353 AssertReturn(!cbImage, VERR_INVALID_PARAMETER); 1354 } 1355 AssertReturn(cbImage || cSegs, VERR_INVALID_PARAMETER); 1356 AssertPtrNullReturn(pUuid, VERR_INVALID_POINTER); 1357 AssertReturn(!(fFlags & ~(RTDBGMOD_F_NOT_DEFERRED)), VERR_INVALID_PARAMETER); 1358 1359 int rc = rtDbgModLazyInit(); 1360 if (RT_FAILURE(rc)) 1361 return rc; 1362 1363 uint64_t fDbgCfg = 0; 1364 if (hDbgCfg) 1365 { 1366 rc = RTDbgCfgQueryUInt(hDbgCfg, RTDBGCFGPROP_FLAGS, &fDbgCfg); 1367 AssertRCReturn(rc, rc); 1368 } 1369 1370 /* 1371 * Allocate a new module instance. 1372 */ 1373 PRTDBGMODINT pDbgMod = (PRTDBGMODINT)RTMemAllocZ(sizeof(*pDbgMod)); 1374 if (!pDbgMod) 1375 return VERR_NO_MEMORY; 1376 pDbgMod->u32Magic = RTDBGMOD_MAGIC; 1377 pDbgMod->cRefs = 1; 1378 rc = RTCritSectInit(&pDbgMod->CritSect); 1379 if (RT_SUCCESS(rc)) 1380 { 1381 pDbgMod->pszName = RTStrCacheEnterLower(g_hDbgModStrCache, pszName); 1382 if (pDbgMod->pszName) 1383 { 1384 pDbgMod->pszImgFile = RTStrCacheEnter(g_hDbgModStrCache, pszFilename); 1385 if (pDbgMod->pszImgFile) 1386 { 1387 RTStrCacheRetain(pDbgMod->pszImgFile); 1388 pDbgMod->pszImgFileSpecified = pDbgMod->pszImgFile; 1389 1390 /* 1391 * Load it immediately? 1392 */ 1393 if ( !(fDbgCfg & RTDBGCFG_FLAGS_DEFERRED) 1394 || (!cbImage && !cSegs) 1395 || (fFlags & RTDBGMOD_F_NOT_DEFERRED) ) 1396 rc = rtDbgModFromMachOImageWorker(pDbgMod, enmArch, cbImage, cSegs, paSegs, pUuid, hDbgCfg); 1397 else 1398 { 1399 /* 1400 * Procrastinate. Need image size atm. 1401 */ 1402 uint32_t uRvaMax = cbImage; 1403 if (!uRvaMax) 1404 for (uint32_t iSeg = 0; iSeg < cSegs; iSeg++) 1405 { 1406 if ( paSegs[iSeg].uRva > uRvaMax 1407 && paSegs[iSeg].uRva - uRvaMax < _1M) 1408 uRvaMax = paSegs[iSeg].uRva; 1409 uRvaMax += paSegs[iSeg].cb; 1410 } 1411 1412 PRTDBGMODDEFERRED pDeferred; 1413 rc = rtDbgModDeferredCreate(pDbgMod, rtDbgModFromMachOImageDeferredCallback, uRvaMax, hDbgCfg, 1414 RT_OFFSETOF(RTDBGMODDEFERRED, u.MachO.aSegs[cSegs]), 1415 &pDeferred); 1416 if (RT_SUCCESS(rc)) 1417 { 1418 pDeferred->u.MachO.Uuid = *pUuid; 1419 pDeferred->u.MachO.enmArch = enmArch; 1420 pDeferred->u.MachO.cSegs = cSegs; 1421 if (cSegs) 1422 { 1423 memcpy(&pDeferred->u.MachO.aSegs, paSegs, cSegs * sizeof(paSegs[0])); 1424 if (!cbImage) 1425 { 1426 /* If we calculated a cbImage above, do corresponding RVA adjustments. */ 1427 uRvaMax = 0; 1428 for (uint32_t iSeg = 0; iSeg < cSegs; iSeg++) 1429 { 1430 if ( paSegs[iSeg].uRva > uRvaMax 1431 && paSegs[iSeg].uRva - uRvaMax < _1M) 1432 uRvaMax = paSegs[iSeg].uRva; 1433 else 1434 pDeferred->u.MachO.aSegs[iSeg].uRva = uRvaMax; 1435 uRvaMax += paSegs[iSeg].cb; 1436 } 1437 } 1438 } 1439 } 1440 } 1441 if (RT_SUCCESS(rc)) 1442 { 1443 *phDbgMod = pDbgMod; 1444 return VINF_SUCCESS; 1445 } 1446 1447 /* Failed, bail out. */ 1448 RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszName); 1449 } 1450 else 1451 rc = VERR_NO_STR_MEMORY; 1452 RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFileSpecified); 1453 RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFile); 1454 } 1455 else 1456 rc = VERR_NO_STR_MEMORY; 1457 RTCritSectDelete(&pDbgMod->CritSect); 1458 } 1459 1460 RTMemFree(pDbgMod); 1461 return rc; 1462 } 1463 1464 1465 1466 RT_EXPORT_SYMBOL(RTDbgModCreateFromMachOImage); 1467 1468 1469 1172 1470 /** 1173 1471 * Destroys an module after the reference count has reached zero. -
trunk/src/VBox/Runtime/common/dbg/dbgmoddeferred.cpp
r46281 r49044 439 439 * 440 440 */ 441 442 /** @interface_method_impl{RTDBGMODVTIMG,pfnQueryProp} */ 443 static DECLCALLBACK(int ) rtDbgModDeferredImg_QueryProp(PRTDBGMODINT pMod, RTLDRPROP enmProp, void *pvBuf, size_t cbBuf) 444 { 445 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/); 446 if (RT_SUCCESS(rc)) 447 rc = pMod->pImgVt->pfnQueryProp(pMod, enmProp, pvBuf, cbBuf); 448 return rc; 449 } 441 450 442 451 … … 593 602 /*.pfnGetFormat = */ rtDbgModDeferredImg_GetFormat, 594 603 /*.pfnGetArch = */ rtDbgModDeferredImg_GetArch, 604 /*.pfnQueryProp = */ rtDbgModDeferredImg_QueryProp, 595 605 596 606 /*.u32EndMagic = */ RTDBGMODVTIMG_MAGIC … … 608 618 * @param hDbgCfg The debug config handle. Can be NIL. A 609 619 * reference will be retained. 620 * @param cbDeferred The size of the deferred instance data, 0 if the 621 * default structure is good enough. 610 622 * @param ppDeferred Where to return the instance data. Can be NULL. 611 623 */ 612 624 DECLHIDDEN(int) rtDbgModDeferredCreate(PRTDBGMODINT pDbgMod, PFNRTDBGMODDEFERRED pfnDeferred, RTUINTPTR cbImage, 613 RTDBGCFG hDbgCfg, PRTDBGMODDEFERRED *ppDeferred)625 RTDBGCFG hDbgCfg, size_t cbDeferred, PRTDBGMODDEFERRED *ppDeferred) 614 626 { 615 627 AssertReturn(!pDbgMod->pDbgVt, VERR_DBG_MOD_IPE); 616 628 617 PRTDBGMODDEFERRED pDeferred = (PRTDBGMODDEFERRED)RTMemAllocZ(sizeof(*pDeferred)); 629 if (cbDeferred < sizeof(RTDBGMODDEFERRED)) 630 cbDeferred = sizeof(RTDBGMODDEFERRED); 631 PRTDBGMODDEFERRED pDeferred = (PRTDBGMODDEFERRED)RTMemAllocZ(cbDeferred); 618 632 if (!pDeferred) 619 633 return VERR_NO_MEMORY; -
trunk/src/VBox/Runtime/common/dbg/dbgmodldr.cpp
r46266 r49044 5 5 6 6 /* 7 * Copyright (C) 2011 Oracle Corporation7 * Copyright (C) 2011-2013 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 59 59 typedef RTDBGMODLDR *PRTDBGMODLDR; 60 60 61 62 63 /** @interface_method_impl{RTDBGMODVTIMG,pfnQueryProp} */ 64 static DECLCALLBACK(int) rtDbgModLdr_QueryProp(PRTDBGMODINT pMod, RTLDRPROP enmProp, void *pvBuf, size_t cbBuf) 65 { 66 PRTDBGMODLDR pThis = (PRTDBGMODLDR)pMod->pvImgPriv; 67 return RTLdrQueryProp(pThis->hLdrMod, enmProp, pvBuf, cbBuf); 68 } 61 69 62 70 … … 216 224 /*.pfnGetFormat = */ rtDbgModLdr_GetFormat, 217 225 /*.pfnGetArch = */ rtDbgModLdr_GetArch, 226 /*.pfnQueryProp = */ rtDbgModLdr_QueryProp, 218 227 219 228 /*.u32EndMagic = */ RTDBGMODVTIMG_MAGIC -
trunk/src/VBox/Runtime/common/ldr/ldr.cpp
r48935 r49044 5 5 6 6 /* 7 * Copyright (C) 2006-201 1Oracle Corporation7 * Copyright (C) 2006-2013 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 148 148 * Validate input. 149 149 */ 150 if (hLdrMod == NIL_RTLDRMOD) 151 return VINF_SUCCESS; 150 152 AssertMsgReturn(rtldrIsValid(hLdrMod), ("hLdrMod=%p\n", hLdrMod), VERR_INVALID_HANDLE); 151 153 PRTLDRMODINTERNAL pMod = (PRTLDRMODINTERNAL)hLdrMod; -
trunk/src/VBox/Runtime/common/ldr/ldrELFRelocatable.cpp.h
r47290 r49044 1401 1401 RTLDRELF_NAME(RvaToSegOffset), 1402 1402 RTLDRELF_NAME(ReadDbgInfo), 1403 NULL /*pfnQueryProp*/, 1403 1404 42 1404 1405 }; -
trunk/src/VBox/Runtime/common/ldr/ldrEx.cpp
r48935 r49044 5 5 6 6 /* 7 * Copyright (C) 2006-201 1Oracle Corporation7 * Copyright (C) 2006-2013 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 540 540 541 541 542 RTDECL(int) RTLdrQueryProp(RTLDRMOD hLdrMod, RTLDRPROP enmProp, void *pvBuf, size_t cbBuf) 543 { 544 AssertMsgReturn(rtldrIsValid(hLdrMod), ("hLdrMod=%p\n", hLdrMod), RTLDRENDIAN_INVALID); 545 PRTLDRMODINTERNAL pMod = (PRTLDRMODINTERNAL)hLdrMod; 546 547 /* 548 * Do some pre screening of the input 549 */ 550 switch (enmProp) 551 { 552 case RTLDRPROP_UUID: 553 AssertReturn(cbBuf == sizeof(RTUUID), VERR_INVALID_PARAMETER); 554 break; 555 case RTLDRPROP_TIMESTAMP_SECONDS: 556 AssertReturn(cbBuf == sizeof(int32_t) || cbBuf == sizeof(int64_t), VERR_INVALID_PARAMETER); 557 break; 558 default: 559 AssertFailedReturn(VERR_INVALID_FUNCTION); 560 } 561 AssertPtrReturn(pvBuf, VERR_INVALID_POINTER); 562 563 /* 564 * Call the image specific worker, if there is one. 565 */ 566 if (!pMod->pOps->pfnQueryProp) 567 return VERR_NOT_SUPPORTED; 568 return pMod->pOps->pfnQueryProp(pMod, enmProp, pvBuf, cbBuf); 569 } 570 RT_EXPORT_SYMBOL(RTLdrQueryProp); 571 572 542 573 /** 543 574 * Internal method used by the IPRT debug bits. -
trunk/src/VBox/Runtime/common/ldr/ldrNative.cpp
r49040 r49044 71 71 rtldrNativeEnumSymbols, 72 72 /* ext: */ 73 NULL, 73 74 NULL, 74 75 NULL, -
trunk/src/VBox/Runtime/common/ldr/ldrPE.cpp
r48935 r49044 1490 1490 1491 1491 1492 /** @interface_method_impl{RTLDROPS,pfnQueryProp} */ 1493 static DECLCALLBACK(int) rtldrPE_QueryProp(PRTLDRMODINTERNAL pMod, RTLDRPROP enmProp, void *pvBuf, size_t cbBuf) 1494 { 1495 PRTLDRMODPE pModPe = (PRTLDRMODPE)pMod; 1496 switch (enmProp) 1497 { 1498 case RTLDRPROP_TIMESTAMP_SECONDS: 1499 if (cbBuf == sizeof(int32_t)) 1500 *(int32_t *)pvBuf = pModPe->uTimestamp; 1501 else if (cbBuf == sizeof(int64_t)) 1502 *(int64_t *)pvBuf = pModPe->uTimestamp; 1503 else 1504 return VERR_INVALID_PARAMETER; 1505 break; 1506 1507 default: 1508 return VERR_NOT_FOUND; 1509 } 1510 return VINF_SUCCESS; 1511 } 1512 1513 1492 1514 /** @copydoc RTLDROPS::pfnDone */ 1493 1515 static DECLCALLBACK(int) rtldrPEDone(PRTLDRMODINTERNAL pMod) … … 1543 1565 rtldrPE_RvaToSegOffset, 1544 1566 NULL, 1567 rtldrPE_QueryProp, 1545 1568 42 1546 1569 }, … … 1573 1596 rtldrPE_RvaToSegOffset, 1574 1597 NULL, 1598 rtldrPE_QueryProp, 1575 1599 42 1576 1600 }, -
trunk/src/VBox/Runtime/common/ldr/ldrkStuff.cpp
r48935 r49044 149 149 case KLDR_ERR_NOT_DLL: 150 150 case KLDR_ERR_NOT_EXE: 151 AssertMsgFailedReturn(("krc=%d (%#x): %s\n", krc, krc, kErrName(krc)), VERR_ GENERAL_FAILURE);151 AssertMsgFailedReturn(("krc=%d (%#x): %s\n", krc, krc, kErrName(krc)), VERR_LDR_GENERAL_FAILURE); 152 152 153 153 … … 160 160 case KLDR_ERR_PE_BAD_FIXUP: 161 161 case KLDR_ERR_PE_BAD_IMPORT: 162 AssertMsgFailedReturn(("krc=%d (%#x): %s\n", krc, krc, kErrName(krc)), VERR_ GENERAL_FAILURE);162 AssertMsgFailedReturn(("krc=%d (%#x): %s\n", krc, krc, kErrName(krc)), VERR_LDR_GENERAL_FAILURE); 163 163 164 164 case KLDR_ERR_LX_BAD_HEADER: … … 174 174 case KLDR_ERR_LX_BAD_FORWARDER: 175 175 case KLDR_ERR_LX_NRICHAIN_NOT_SUPPORTED: 176 AssertMsgFailedReturn(("krc=%d (%#x): %s\n", krc, krc, kErrName(krc)), VERR_GENERAL_FAILURE); 177 176 AssertMsgFailedReturn(("krc=%d (%#x): %s\n", krc, krc, kErrName(krc)), VERR_LDR_GENERAL_FAILURE); 177 178 case KLDR_ERR_MACHO_UNSUPPORTED_FILE_TYPE: return VERR_LDR_GENERAL_FAILURE; 178 179 case KLDR_ERR_MACHO_OTHER_ENDIAN_NOT_SUPPORTED: 179 180 case KLDR_ERR_MACHO_BAD_HEADER: 180 case KLDR_ERR_MACHO_UNSUPPORTED_FILE_TYPE:181 181 case KLDR_ERR_MACHO_UNSUPPORTED_MACHINE: 182 182 case KLDR_ERR_MACHO_BAD_LOAD_COMMAND: … … 195 195 case KLDR_ERR_MACHO_BAD_SYMBOL: 196 196 case KLDR_ERR_MACHO_UNSUPPORTED_FIXUP_TYPE: 197 AssertMsgFailedReturn(("krc=%d (%#x): %s\n", krc, krc, kErrName(krc)), VERR_ GENERAL_FAILURE);197 AssertMsgFailedReturn(("krc=%d (%#x): %s\n", krc, krc, kErrName(krc)), VERR_LDR_GENERAL_FAILURE); 198 198 199 199 default: … … 837 837 838 838 839 /** @interface_method_impl{RTLDROPS,pfnQueryProp} */ 840 static DECLCALLBACK(int) rtkldr_QueryProp(PRTLDRMODINTERNAL pMod, RTLDRPROP enmProp, void *pvBuf, size_t cbBuf) 841 { 842 PRTLDRMODKLDR pThis = (PRTLDRMODKLDR)pMod; 843 int rc; 844 switch (enmProp) 845 { 846 case RTLDRPROP_UUID: 847 rc = kLdrModQueryImageUuid(pThis->pMod, /*pvBits*/ NULL, (uint8_t *)pvBuf, cbBuf); 848 if (rc == KLDR_ERR_NO_IMAGE_UUID) 849 return VERR_NOT_FOUND; 850 AssertReturn(rc == 0, VERR_INVALID_PARAMETER); 851 break; 852 853 default: 854 return VERR_NOT_FOUND; 855 } 856 return VINF_SUCCESS; 857 } 858 859 839 860 /** 840 861 * Operations for a kLdr module. … … 859 880 rtkldr_RvaToSegOffset, 860 881 rtkldr_ReadDbgInfo, 882 rtkldr_QueryProp, 861 883 42 862 884 }; -
trunk/src/VBox/Runtime/include/internal/dbgmod.h
r46266 r49044 227 227 */ 228 228 DECLCALLBACKMEMBER(RTLDRARCH, pfnGetArch)(PRTDBGMODINT pMod); 229 230 /** 231 * Generic method for querying image properties. 232 * 233 * @returns IPRT status code. 234 * @param pMod Pointer to the module structure. 235 * @param enmLdrProp The property to query. 236 * @param pvBuf Pointer to the return buffer. 237 * @param cbBuf The size of the return buffer. 238 * @sa RTLdrQueryProp 239 */ 240 DECLCALLBACKMEMBER(int, pfnQueryProp)(PRTDBGMODINT pMod, RTLDRPROP enmProp, void *pvBuf, size_t cbBuf); 229 241 230 242 /** For catching initialization errors (RTDBGMODVTIMG_MAGIC). */ … … 559 571 uint32_t uCrc32; 560 572 } GnuDebugLink; 573 574 struct 575 { 576 /** The image UUID. */ 577 RTUUID Uuid; 578 /** Image architecture. */ 579 RTLDRARCH enmArch; 580 /** Number of segment mappings. */ 581 uint32_t cSegs; 582 /** Segment mappings. */ 583 RTDBGSEGMENT aSegs[1]; 584 } MachO; 561 585 } u; 562 586 } RTDBGMODDEFERRED; … … 617 641 618 642 643 /** 644 * Special segment package used passing segment order information for mach-o 645 * images (mainly mach_kernel, really). 646 * 647 * Passes to rtDbgModDwarf_TryOpen via RTDBGMODINF::pvDbgPriv. 648 */ 649 typedef struct RTDBGDWARFSEGPKG 650 { 651 /** Pointer to the segment array. */ 652 PCRTDBGSEGMENT paSegs; 653 /** Number of segments. */ 654 uint32_t cSegs; 655 /** For use more internal use in file locator callbacks. */ 656 RTLDRARCH enmArch; 657 /** For use more internal use in file locator callbacks. */ 658 PCRTUUID pUuid; 659 } RTDBGDWARFSEGPKG; 660 /** Pointer to a const segment package. */ 661 typedef RTDBGDWARFSEGPKG const *PCRTDBGDWARFSEGPKG; 662 663 619 664 extern DECLHIDDEN(RTSTRCACHE) g_hDbgModStrCache; 620 665 extern DECLHIDDEN(RTDBGMODVTDBG const) g_rtDbgModVtDbgCodeView; … … 637 682 DECLHIDDEN(int) rtDbgModCreateForExports(PRTDBGMODINT pDbgMod); 638 683 DECLHIDDEN(int) rtDbgModDeferredCreate(PRTDBGMODINT pDbgMod, PFNRTDBGMODDEFERRED pfnDeferred, RTUINTPTR cbImage, 639 RTDBGCFG hDbgCfg, PRTDBGMODDEFERRED *ppDeferred);684 RTDBGCFG hDbgCfg, size_t cbDeferred, PRTDBGMODDEFERRED *ppDeferred); 640 685 641 686 DECLHIDDEN(int) rtDbgModLdrOpenFromHandle(PRTDBGMODINT pDbgMod, RTLDRMOD hLdrMod); -
trunk/src/VBox/Runtime/include/internal/ldr.h
r46593 r49044 312 312 * @returns IPRT status code. 313 313 * 314 * @param pMod Pointer to the loader module structure. 314 315 * @param pvBuf The buffer to read into. 315 316 * @param iDbgInfo The debug info ordinal number if the request … … 321 322 */ 322 323 DECLCALLBACKMEMBER(int, pfnReadDbgInfo)(PRTLDRMODINTERNAL pMod, uint32_t iDbgInfo, RTFOFF off, size_t cb, void *pvBuf); 324 325 326 327 /** 328 * Generic method for querying image properties. 329 * 330 * @returns IPRT status code. 331 * @retval VERR_NOT_SUPPORTED if the property query isn't supported (either all 332 * or that specific property). 333 * @retval VERR_NOT_FOUND the property was not found in the module. 334 * 335 * @param pMod Pointer to the loader module structure. 336 * @param enmLdrProp The property to query (valid). 337 * @param pvBuf Pointer to the return buffer (valid). 338 * @param cbBuf The size of the return buffer (valid as per 339 * property). 340 */ 341 DECLCALLBACKMEMBER(int, pfnQueryProp)(PRTLDRMODINTERNAL pMod, RTLDRPROP enmProp, void *pvBuf, size_t cbBuf); 323 342 324 343 /** Dummy entry to make sure we've initialized it all. */ -
trunk/src/VBox/Runtime/tools/Makefile.kmk
r45929 r49044 71 71 RTNtDbgHelp_SOURCES = RTNtDbgHelp.cpp 72 72 73 # RTDbgSymCache - Symbol cache manager. 74 PROGRAMS += RTDbgSymCache 75 RTDbgSymCache_TEMPLATE = VBOXR3TSTEXE 76 RTDbgSymCache_SOURCES = RTDbgSymCache.cpp 77 73 78 endif # !VBOX_ONLY_EXTPACKS_USE_IMPLIBS 74 79 -
trunk/src/libs/kStuff
- Property svn:externals changed from to
Note:
See TracChangeset
for help on using the changeset viewer.