Changeset 83085 in vbox
- Timestamp:
- Feb 15, 2020 9:19:54 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 4 edited
-
include/iprt/dbg.h (modified) (1 diff)
-
src/VBox/Debugger/DBGPlugInDarwin.cpp (modified) (2 diffs)
-
src/VBox/Runtime/common/dbg/dbgmod.cpp (modified) (5 diffs)
-
src/VBox/VMM/VMMR3/DBGFR3ModInMem.cpp (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/dbg.h
r83084 r83085 1238 1238 uint32_t uCrc32, RTDBGCFG hDbgCfg); 1239 1239 RTDECL(int) RTDbgModCreateFromMachOImage(PRTDBGMOD phDbgMod, const char *pszFilename, const char *pszName, 1240 RTLDRARCH enmArch, uint32_t cbImage, uint32_t cSegs, PCRTDBGSEGMENT paSegs,1241 PCRT UUID pUuid, RTDBGCFG hDbgCfg, uint32_t fFlags);1240 RTLDRARCH enmArch, PRTLDRMOD phLdrModIn, uint32_t cbImage, uint32_t cSegs, 1241 PCRTDBGSEGMENT paSegs, PCRTUUID pUuid, RTDBGCFG hDbgCfg, uint32_t fFlags); 1242 1242 1243 1243 /** @name Flags for RTDbgModCreate and friends. -
trunk/src/VBox/Debugger/DBGPlugInDarwin.cpp
r83084 r83085 407 407 * @param uMaxAddr Highest allowed address. 408 408 */ 409 static intdbgDiggerDarwinIsSegmentPresent(PUVM pUVM, uint64_t uSegAddr, uint64_t cbSeg, uint64_t uMinAddr, uint64_t uMaxAddr)409 static bool dbgDiggerDarwinIsSegmentPresent(PUVM pUVM, uint64_t uSegAddr, uint64_t cbSeg, uint64_t uMinAddr, uint64_t uMaxAddr) 410 410 { 411 411 /* … … 657 657 */ 658 658 RTDBGMOD hMod; 659 rc = RTDbgModCreateFromMachOImage(&hMod, pszName, NULL, f64Bit ? RTLDRARCH_AMD64 : RTLDRARCH_X86_32, 0 /*cbImage*/,660 cSegs, aSegs, &Uuid, DBGFR3AsGetConfig(pUVM),659 rc = RTDbgModCreateFromMachOImage(&hMod, pszName, NULL, f64Bit ? RTLDRARCH_AMD64 : RTLDRARCH_X86_32, NULL /*phLdrModIn*/, 660 0 /*cbImage*/, cSegs, aSegs, &Uuid, DBGFR3AsGetConfig(pUVM), 661 661 RTDBGMOD_F_NOT_DEFERRED | (fHasLinkEdit ? RTDBGMOD_F_MACHO_LOAD_LINKEDIT : 0)); 662 662 663 664 /* 665 * If module creation failed and we've got a linkedit segment, try open the 666 * image in-memory, because that will at a minimum give us symbol table symbols. 667 */ 668 if (RT_FAILURE(rc) && fHasLinkEdit) 669 { 670 DBGFADDRESS DbgfAddr; 671 RTERRINFOSTATIC ErrInfo; 672 rc = DBGFR3ModInMem(pUVM, DBGFR3AddrFromFlat(pUVM, &DbgfAddr, uModAddr), 673 DBGFMODINMEM_F_NO_CONTAINER_FALLBACK, 674 pszName, NULL /*pszFilename*/, f64Bit ? RTLDRARCH_AMD64 : RTLDRARCH_X86_32, 0 /*cbImage */, 675 &hMod, RTErrInfoInitStatic(&ErrInfo)); 676 if (RT_FAILURE(rc)) 677 LogRel(("OSXDig: Failed to do an in-memory-opening of '%s' at %#RX64: %Rrc%s%s\n", pszName, uModAddr, rc, 678 RTErrInfoIsSet(&ErrInfo.Core) ? " - " : "", RTErrInfoIsSet(&ErrInfo.Core) ? ErrInfo.Core.pszMsg : "")); 679 } 680 681 /* 682 * Final fallback is a container module. 683 */ 663 684 if (RT_FAILURE(rc)) 664 685 { 665 /** @todo try open in memory. */666 667 /*668 * Final fallback is a container module.669 */670 686 rc = RTDbgModCreate(&hMod, pszName, 0, 0); 671 687 if (RT_FAILURE(rc)) -
trunk/src/VBox/Runtime/common/dbg/dbgmod.cpp
r83084 r83085 1390 1390 1391 1391 1392 RTDECL(int) RTDbgModCreateFromMachOImage(PRTDBGMOD phDbgMod, const char *pszFilename, const char *pszName, 1393 RTLDRARCH enmArch, uint32_t cbImage, uint32_t cSegs, PCRTDBGSEGMENT paSegs,1392 RTDECL(int) RTDbgModCreateFromMachOImage(PRTDBGMOD phDbgMod, const char *pszFilename, const char *pszName, RTLDRARCH enmArch, 1393 PRTLDRMOD phLdrModIn, uint32_t cbImage, uint32_t cSegs, PCRTDBGSEGMENT paSegs, 1394 1394 PCRTUUID pUuid, RTDBGCFG hDbgCfg, uint32_t fFlags) 1395 1395 { … … 1410 1410 AssertReturn(!cbImage, VERR_INVALID_PARAMETER); 1411 1411 } 1412 AssertReturn(cbImage || cSegs, VERR_INVALID_PARAMETER);1413 1412 AssertPtrNullReturn(pUuid, VERR_INVALID_POINTER); 1414 1413 AssertReturn(!(fFlags & ~RTDBGMOD_F_VALID_MASK), VERR_INVALID_FLAGS); 1414 1415 AssertPtrNullReturn(phLdrModIn, VERR_INVALID_POINTER); 1416 RTLDRMOD hLdrModIn = phLdrModIn ? *phLdrModIn : NIL_RTLDRMOD; 1417 AssertReturn(hLdrModIn == NIL_RTLDRMOD || RTLdrSize(hLdrModIn) != ~(size_t)0, VERR_INVALID_HANDLE); 1418 1419 AssertReturn(cbImage || cSegs || hLdrModIn != NIL_RTLDRMOD, VERR_INVALID_PARAMETER); 1415 1420 1416 1421 int rc = rtDbgModLazyInit(); … … 1423 1428 rc = RTDbgCfgQueryUInt(hDbgCfg, RTDBGCFGPROP_FLAGS, &fDbgCfg); 1424 1429 AssertRCReturn(rc, rc); 1430 } 1431 1432 /* 1433 * If we got no UUID but the caller passed in a module handle, try 1434 * query the UUID from it. 1435 */ 1436 RTUUID UuidFromImage = RTUUID_INITIALIZE_NULL; 1437 if ((!pUuid || RTUuidIsNull(pUuid)) && hLdrModIn != NIL_RTLDRMOD) 1438 { 1439 rc = RTLdrQueryProp(hLdrModIn, RTLDRPROP_UUID, &UuidFromImage, sizeof(UuidFromImage)); 1440 if (RT_SUCCESS(rc)) 1441 pUuid = &UuidFromImage; 1425 1442 } 1426 1443 … … 1451 1468 || cSegs /* for the time being. */ 1452 1469 || (!cbImage && !cSegs) 1453 || (fFlags & RTDBGMOD_F_NOT_DEFERRED) ) 1470 || (fFlags & RTDBGMOD_F_NOT_DEFERRED) 1471 || hLdrModIn != NIL_RTLDRMOD) 1472 { 1454 1473 rc = rtDbgModFromMachOImageWorker(pDbgMod, enmArch, cbImage, cSegs, paSegs, pUuid, hDbgCfg, fFlags); 1474 if (RT_FAILURE(rc) && hLdrModIn != NIL_RTLDRMOD) 1475 { 1476 /* 1477 * Create module based on exports from hLdrModIn. 1478 */ 1479 if (!cbImage) 1480 cbImage = (uint32_t)RTLdrSize(hLdrModIn); 1481 pDbgMod->pImgVt = &g_rtDbgModVtImgLdr; 1482 1483 rc = rtDbgModLdrOpenFromHandle(pDbgMod, hLdrModIn); 1484 if (RT_SUCCESS(rc)) 1485 { 1486 /* We now own the loader handle, so clear the caller variable. */ 1487 if (phLdrModIn) 1488 *phLdrModIn = NIL_RTLDRMOD; 1489 1490 /** @todo delayed exports stuff */ 1491 rc = rtDbgModCreateForExports(pDbgMod); 1492 } 1493 } 1494 } 1455 1495 else 1456 1496 { … … 1493 1533 return rc; 1494 1534 } 1495 1496 1497 1498 1535 RT_EXPORT_SYMBOL(RTDbgModCreateFromMachOImage); 1499 1536 -
trunk/src/VBox/VMM/VMMR3/DBGFR3ModInMem.cpp
r82968 r83085 29 29 #include <iprt/path.h> 30 30 #include <iprt/string.h> 31 #include <iprt/sort.h> 31 32 #include <iprt/formats/pecoff.h> 32 33 #include <iprt/formats/mz.h> 33 34 #include <iprt/formats/elf.h> 35 #include <iprt/formats/mach-o.h> 34 36 35 37 … … 37 39 * Structures and Typedefs * 38 40 *********************************************************************************************************************************/ 41 /** Entry for mapping file offset to memory location. */ 42 typedef struct DBGFMODINMEMMAPPING 43 { 44 /** The file offset. */ 45 uint32_t offFile; 46 /** The file size of this mapping. */ 47 uint32_t cbFile; 48 /** The size of this mapping. */ 49 uint32_t cbMem; 50 /** The offset to the memory from the start of the image. 51 * @note This can be negative (for mach_kernel). */ 52 int32_t offMem; 53 } DBGFMODINMEMMAPPING; 54 typedef DBGFMODINMEMMAPPING *PDBGFMODINMEMMAPPING; 55 typedef DBGFMODINMEMMAPPING const *PCDBGFMODINMEMMAPPING; 56 57 /** 58 * Common in-memory reader instance data. 59 */ 60 typedef struct DBGFMODINMEMRDR 61 { 62 /** The VM handle (referenced). */ 63 PUVM pUVM; 64 /** The image base. */ 65 DBGFADDRESS ImageAddr; 66 /** The file size, based on the offFile and cbFile of the last mapping. */ 67 uint32_t cbFile; 68 /** Number of entries in the aMappings table. */ 69 uint32_t cMappings; 70 /** Mapping hint. */ 71 uint32_t iHint; 72 /** Mapping file offset to memory offsets, ordered by file offset. */ 73 DBGFMODINMEMMAPPING aMappings[RT_FLEXIBLE_ARRAY_NESTED]; 74 } DBGFMODINMEMRDR; 75 /** Pointer to the common instance data for an in-memory file reader. */ 76 typedef DBGFMODINMEMRDR *PDBGFMODINMEMRDR; 77 39 78 /** 40 79 * The WinNT digger's loader reader instance data. … … 80 119 IMAGE_NT_HEADERS32 Nt32; 81 120 IMAGE_NT_HEADERS64 Nt64; 121 mach_header_64 MachoHdr; 122 DBGFMODINMEMMAPPING aMappings[0x2000 / sizeof(DBGFMODINMEMMAPPING)]; 82 123 } DBGFMODINMEMBUF; 83 124 /** Pointer to stack buffer. */ … … 130 171 131 172 return pszBuf; 173 } 174 175 176 /** 177 * @callback_method_impl{PFNRTLDRRDRMEMREAD} 178 */ 179 static DECLCALLBACK(int) dbgfModInMemCommon_Read(void *pvBuf, size_t cb, size_t off, void *pvUser) 180 { 181 PDBGFMODINMEMRDR pThis = (PDBGFMODINMEMRDR)pvUser; 182 uint32_t offFile = (uint32_t)off; 183 AssertReturn(offFile == off, VERR_INVALID_PARAMETER); 184 185 /* 186 * Set i to a mapping that starts at or before the specified offset. 187 * ASSUMING aMappings are sorted by offFile. 188 */ 189 uint32_t i = pThis->iHint; 190 if (pThis->aMappings[i].offFile > offFile) 191 { 192 i = pThis->cMappings; /** @todo doesn't need to start from the end here... */ 193 while (i-- > 0) 194 if (offFile >= pThis->aMappings[i].offFile) 195 break; 196 pThis->iHint = i; 197 } 198 199 while (cb > 0) 200 { 201 uint32_t offNextMap = i + 1 < pThis->cMappings ? pThis->aMappings[i + 1].offFile 202 : pThis->aMappings[i].offFile + RT_MAX(pThis->aMappings[i].cbFile, pThis->aMappings[i].cbMem); 203 uint32_t offMap = offFile - pThis->aMappings[i].offFile; 204 205 /* Read file bits backed by memory. */ 206 if (offMap < pThis->aMappings[i].cbMem) 207 { 208 uint32_t cbToRead = pThis->aMappings[i].cbMem - offMap; 209 if (cbToRead > cb) 210 cbToRead = (uint32_t)cb; 211 212 DBGFADDRESS Addr = pThis->ImageAddr; 213 DBGFR3AddrAdd(&Addr, pThis->aMappings[i].offMem + offMap); 214 215 int rc = DBGFR3MemRead(pThis->pUVM, 0 /*idCpu*/, &Addr, pvBuf, cbToRead); 216 if (RT_FAILURE(rc)) 217 return rc; 218 219 /* Done? */ 220 if (cbToRead == cb) 221 break; 222 223 offFile += cbToRead; 224 cb -= cbToRead; 225 pvBuf = (char *)pvBuf + cbToRead; 226 } 227 228 /* Mind the gap. */ 229 if (offNextMap > offFile) 230 { 231 uint32_t cbZero = offNextMap - offFile; 232 if (cbZero > cb) 233 { 234 RT_BZERO(pvBuf, cb); 235 break; 236 } 237 238 RT_BZERO(pvBuf, cbZero); 239 offFile += cbZero; 240 cb -= cbZero; 241 pvBuf = (char *)pvBuf + cbZero; 242 } 243 244 pThis->iHint = ++i; 245 } 246 247 return VINF_SUCCESS; 248 } 249 250 251 /** 252 * @callback_method_impl{PFNRTLDRRDRMEMDTOR} 253 */ 254 static DECLCALLBACK(void) dbgfModInMemCommon_Dtor(void *pvUser, size_t cbImage) 255 { 256 PDBGFMODINMEMRDR pThis = (PDBGFMODINMEMRDR)pvUser; 257 RT_NOREF(cbImage); 258 259 VMR3ReleaseUVM(pThis->pUVM); 260 pThis->pUVM = NULL; 261 262 RTMemFree(pThis); 263 } 264 265 266 /** 267 * @callback_method_impl{FNRTSORTCMP} 268 */ 269 static DECLCALLBACK(int) dbgfModInMemCompMappings(void const *pvElement1, void const *pvElement2, void *pvUser) 270 { 271 RT_NOREF(pvUser); 272 PCDBGFMODINMEMMAPPING pElement1 = (PCDBGFMODINMEMMAPPING)pvElement1; 273 PCDBGFMODINMEMMAPPING pElement2 = (PCDBGFMODINMEMMAPPING)pvElement2; 274 if (pElement1->offFile < pElement2->offFile) 275 return -1; 276 if (pElement1->offFile > pElement2->offFile) 277 return 1; 278 if (pElement1->cbFile < pElement2->cbFile) 279 return -1; 280 if (pElement1->cbFile > pElement2->cbFile) 281 return 1; 282 if (pElement1->offMem < pElement2->offMem) 283 return -1; 284 if (pElement1->offMem > pElement2->offMem) 285 return 1; 286 if (pElement1->cbMem < pElement2->cbMem) 287 return -1; 288 if (pElement1->cbMem > pElement2->cbMem) 289 return 1; 290 return 0; 291 } 292 293 294 static int dbgfModInMemCommon_Init(PDBGFMODINMEMRDR pThis, PUVM pUVM, PCDBGFADDRESS pImageAddr,PCDBGFMODINMEMMAPPING paMappings, 295 uint32_t cMappings, const char *pszName, RTLDRARCH enmArch, 296 PRTLDRMOD phLdrMod, PRTERRINFO pErrInfo) 297 { 298 /* 299 * Initialize the reader instance. 300 */ 301 VMR3RetainUVM(pUVM); 302 pThis->pUVM = pUVM; 303 pThis->ImageAddr = *pImageAddr; 304 pThis->cMappings = cMappings; 305 pThis->iHint = 0; 306 memcpy(pThis->aMappings, paMappings, cMappings * sizeof(pThis->aMappings[0])); 307 RTSortShell(pThis->aMappings, cMappings, sizeof(pThis->aMappings[0]), dbgfModInMemCompMappings, NULL); 308 pThis->cbFile = pThis->aMappings[cMappings - 1].offFile + pThis->aMappings[cMappings - 1].cbFile; 309 310 /* 311 * Call the loader to open it. 312 * Note! destructore is always called. 313 */ 314 315 RTLDRMOD hLdrMod; 316 int rc = RTLdrOpenInMemory(pszName, RTLDR_O_FOR_DEBUG, enmArch, pThis->cbFile, 317 dbgfModInMemCommon_Read, dbgfModInMemCommon_Dtor, pThis, 318 &hLdrMod, pErrInfo); 319 if (RT_SUCCESS(rc)) 320 *phLdrMod = hLdrMod; 321 else 322 *phLdrMod = NIL_RTLDRMOD; 323 return rc; 132 324 } 133 325 … … 155 347 RT_NOREF(pUVM, fFlags, pszName, pszFilename, enmArch, cbImage, puBuf, phDbgMod); 156 348 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_INVALID_EXE_SIGNATURE, "Found ELF magic at %RGv", pImageAddr->FlatPtr); 349 } 350 351 352 /** 353 * Handles in-memory Mach-O images. 354 * 355 * @returns VBox status code. 356 * @param pUVM The user mode VM handle. 357 * @param pImageAddr The image address. 358 * @param fFlags Flags, DBGFMODINMEM_F_XXX. 359 * @param pszName The module name, optional. 360 * @param pszFilename The image filename, optional. 361 * @param enmArch The image arch if we force it, pass 362 * RTLDRARCH_WHATEVER if you don't care. 363 * @param cbImage Image size. Pass 0 if not known. 364 * @param puBuf The header buffer. 365 * @param phDbgMod Where to return the resulting debug module on success. 366 * @param pErrInfo Where to return extended error info on failure. 367 */ 368 static int dbgfR3ModInMemMachO(PUVM pUVM, PCDBGFADDRESS pImageAddr, uint32_t fFlags, const char *pszName, const char *pszFilename, 369 RTLDRARCH enmArch, uint32_t cbImage, PDBGFMODINMEMBUF puBuf, 370 PRTDBGMOD phDbgMod, PRTERRINFO pErrInfo) 371 { 372 RT_NOREF(cbImage, fFlags); 373 374 /* 375 * Match up enmArch. 376 */ 377 if (enmArch == RTLDRARCH_AMD64) 378 { 379 if (puBuf->MachoHdr.magic != IMAGE_MACHO64_SIGNATURE) 380 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_LDR_ARCH_MISMATCH, "Wanted AMD64 but header is not 64-bit"); 381 if (puBuf->MachoHdr.cputype != CPU_TYPE_X86_64) 382 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_LDR_ARCH_MISMATCH, "Wanted AMD64 but cpu type is %#x instead of %#x", 383 puBuf->MachoHdr.cputype, CPU_TYPE_X86_64); 384 } 385 else if (enmArch == RTLDRARCH_X86_32) 386 { 387 if (puBuf->MachoHdr.magic != IMAGE_MACHO32_SIGNATURE) 388 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_LDR_ARCH_MISMATCH, "Wanted X86_32 but header is not 32-bit"); 389 if (puBuf->MachoHdr.cputype != CPU_TYPE_X86) 390 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_LDR_ARCH_MISMATCH, "Wanted X86_32 but cpu type is %#x instead of %#x", 391 puBuf->MachoHdr.cputype, CPU_TYPE_X86); 392 } 393 else if (enmArch != RTLDRARCH_WHATEVER) 394 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_LDR_ARCH_MISMATCH, "Unsupported enmArch value %s (%d)", 395 RTLdrArchName(enmArch), enmArch); 396 397 /* 398 * Guess the module name if not specified and make sure it conforms to DBGC expectations. 399 */ 400 char szNormalized[128]; 401 if (!pszName) 402 { 403 if (pszFilename) 404 pszName = RTPathFilenameEx(pszFilename, RTPATH_STR_F_STYLE_DOS /*whatever*/); 405 if (!pszName) 406 { 407 RTStrPrintf(szNormalized, sizeof(szNormalized), "image_%#llx", (uint64_t)pImageAddr->FlatPtr); 408 pszName = szNormalized; 409 } 410 } 411 if (pszName != szNormalized) 412 pszName = dbgfR3ModNormalizeName(pszName, szNormalized, sizeof(szNormalized)); 413 414 /* 415 * Read the load commands into memory, they follow the header. Refuse 416 * if there appear to be too many or too much of these. 417 */ 418 uint32_t const cLoadCmds = puBuf->MachoHdr.ncmds; 419 uint32_t const cbLoadCmds = puBuf->MachoHdr.sizeofcmds; 420 if (cLoadCmds > _8K || cLoadCmds < 2) 421 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_LDRMACHO_BAD_HEADER, 422 "ncmds=%u is out of sensible range (2..8192)", cLoadCmds); 423 if (cbLoadCmds > _2M || cbLoadCmds < sizeof(load_command_t) * 2) 424 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_LDRMACHO_BAD_HEADER, 425 "cbLoadCmds=%#x is out of sensible range (8..2MiB)", cbLoadCmds); 426 427 uint8_t *pbLoadCmds = (uint8_t *)RTMemTmpAllocZ(cbLoadCmds); 428 AssertReturn(pbLoadCmds, VERR_NO_TMP_MEMORY); 429 430 uint32_t const cbHdr = puBuf->MachoHdr.magic == IMAGE_MACHO64_SIGNATURE ? sizeof(mach_header_64) : sizeof(mach_header_32); 431 DBGFADDRESS Addr = *pImageAddr; 432 int rc = DBGFR3MemRead(pUVM, 0 /*idCpu*/, DBGFR3AddrAdd(&Addr, cbHdr), pbLoadCmds, cbLoadCmds); 433 if (RT_SUCCESS(rc)) 434 { 435 /* 436 * Scan it for segments so we can tranlate file offsets to virtual 437 * memory locations. 438 */ 439 RTUUID Uuid = RTUUID_INITIALIZE_NULL; 440 uint32_t cMappings = 0; 441 uint32_t offCmd = 0; 442 for (uint32_t iCmd = 0; iCmd < cLoadCmds; iCmd++) 443 { 444 load_command_t const *pCurCmd = (load_command_t const *)&pbLoadCmds[offCmd]; 445 uint32_t const cbCurCmd = offCmd + sizeof(*pCurCmd) <= cbLoadCmds ? pCurCmd->cmdsize : sizeof(*pCurCmd); 446 if (offCmd + cbCurCmd > cbLoadCmds) 447 rc = RTERRINFO_LOG_SET_F(pErrInfo, VERR_LDRMACHO_BAD_LOAD_COMMAND, 448 "Load command #%u @ %#x is out of bounds: size %#x, left %#x", iCmd, offCmd, cbCurCmd, 449 cbLoadCmds - offCmd); 450 else if (pCurCmd->cmd == LC_SEGMENT_64) 451 { 452 segment_command_64 const *pSeg = (segment_command_64 const *)pCurCmd; 453 if (cbCurCmd >= sizeof(*pSeg)) 454 { 455 if (cMappings >= RT_ELEMENTS(puBuf->aMappings)) 456 rc = RTERRINFO_LOG_SET_F(pErrInfo, VERR_OUT_OF_RANGE, "Too many segments!"); 457 else 458 { 459 puBuf->aMappings[cMappings].offFile = pSeg->fileoff; 460 puBuf->aMappings[cMappings].cbFile = pSeg->filesize; 461 puBuf->aMappings[cMappings].offMem = pSeg->vmaddr - pImageAddr->FlatPtr; 462 puBuf->aMappings[cMappings].cbMem = pSeg->vmsize; 463 cMappings++; 464 } 465 } 466 else 467 rc = RTERRINFO_LOG_SET_F(pErrInfo, VERR_LDRMACHO_BAD_LOAD_COMMAND, 468 "Load command #%u @ %#x is too small for a 64-bit segment: %#x", iCmd, offCmd, cbCurCmd); 469 } 470 else if (pCurCmd->cmd == LC_SEGMENT_32) 471 { 472 segment_command_32 const *pSeg = (segment_command_32 const *)pCurCmd; 473 if (cbCurCmd >= sizeof(*pSeg)) 474 { 475 if (cMappings >= RT_ELEMENTS(puBuf->aMappings)) 476 rc = RTERRINFO_LOG_SET_F(pErrInfo, VERR_OUT_OF_RANGE, "Too many segments!"); 477 else 478 { 479 puBuf->aMappings[cMappings].offFile = pSeg->fileoff; 480 puBuf->aMappings[cMappings].cbFile = pSeg->filesize; 481 puBuf->aMappings[cMappings].offMem = pSeg->vmaddr - pImageAddr->FlatPtr; 482 puBuf->aMappings[cMappings].cbMem = pSeg->vmsize; 483 cMappings++; 484 } 485 } 486 else 487 rc = RTERRINFO_LOG_SET_F(pErrInfo, VERR_LDRMACHO_BAD_LOAD_COMMAND, 488 "Load command #%u @ %#x is too small for a 32-bit segment: %#x", iCmd, offCmd, cbCurCmd); 489 } 490 else if (pCurCmd->cmd == LC_UUID && cbCurCmd == sizeof(uuid_command_t)) 491 memcpy(&Uuid, ((uuid_command_t const *)pCurCmd)->uuid, sizeof(Uuid)); 492 493 if (RT_SUCCESS(rc)) 494 offCmd += cbCurCmd; 495 else 496 break; 497 } /* for each command */ 498 499 if (RT_SUCCESS(rc)) 500 { 501 /* 502 * Create generic loader module instance (pThis is tied to it 503 * come rain come shine). 504 */ 505 PDBGFMODINMEMRDR pThis = (PDBGFMODINMEMRDR)RTMemAllocZVar(RT_UOFFSETOF_DYN(DBGFMODINMEMRDR, aMappings[cMappings])); 506 if (pThis) 507 { 508 RTLDRMOD hLdrMod; 509 rc = dbgfModInMemCommon_Init(pThis, pUVM, pImageAddr, puBuf->aMappings, cMappings, 510 pszName, enmArch, &hLdrMod, pErrInfo); 511 if (RT_FAILURE(rc)) 512 hLdrMod = NIL_RTLDRMOD; 513 514 RTDBGMOD hMod; 515 rc = RTDbgModCreateFromMachOImage(&hMod, pszFilename ? pszFilename : pszName, pszName, enmArch, 516 &hLdrMod, 0 /*cbImage*/, 0, NULL, &Uuid, DBGFR3AsGetConfig(pUVM), fFlags); 517 if (RT_SUCCESS(rc)) 518 *phDbgMod = hMod; 519 #if 0 /** @todo later */ 520 else if (!(fFlags & DBGFMODINMEM_F_NO_CONTAINER_FALLBACK)) 521 { 522 /* 523 * Fallback is a container module. 524 */ 525 rc = RTDbgModCreate(&hMod, pszName, cbImage, 0); 526 if (RT_SUCCESS(rc)) 527 { 528 rc = RTDbgModSymbolAdd(hMod, "Headers", 0 /*iSeg*/, 0, cbImage, 0 /*fFlags*/, NULL); 529 AssertRC(rc); 530 } 531 } 532 #endif 533 if (hLdrMod != NIL_RTLDRMOD) 534 RTLdrClose(hLdrMod); 535 } 536 else 537 rc = VERR_NO_MEMORY; 538 } 539 } 540 else 541 RTERRINFO_LOG_SET_F(pErrInfo, rc, "Failed to read %#x bytes of load commands", cbLoadCmds); 542 RTMemTmpFree(pbLoadCmds); 543 return rc; 157 544 } 158 545 … … 671 1058 return dbgfR3ModInMemElf(pUVM, pImageAddr, fFlags, pszName, pszFilename, enmArch, cbImage, &uBuf, phDbgMod, pErrInfo); 672 1059 1060 if ( uBuf.MachoHdr.magic == IMAGE_MACHO64_SIGNATURE 1061 || uBuf.MachoHdr.magic == IMAGE_MACHO32_SIGNATURE) 1062 return dbgfR3ModInMemMachO(pUVM, pImageAddr, fFlags, pszName, pszFilename, enmArch, cbImage, &uBuf, phDbgMod, pErrInfo); 1063 673 1064 uint32_t offNewHdrs; 674 1065 if (uBuf.DosHdr.e_magic == IMAGE_DOS_SIGNATURE)
Note:
See TracChangeset
for help on using the changeset viewer.

