VirtualBox

Ignore:
Timestamp:
May 19, 2013 1:31:13 PM (12 years ago)
Author:
vboxsync
Message:

First part of loading .dSYM bundles.

Location:
trunk/src/VBox/Runtime/common/dbg
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/dbg/dbgcfg.cpp

    r46108 r46161  
    3333#include "internal/iprt.h"
    3434
     35#include <iprt/alloca.h>
    3536#include <iprt/asm.h>
    3637#include <iprt/assert.h>
     
    626627    if (pThis->fFlags & RTDBGCFG_FLAGS_NO_SYM_SRV)
    627628        return VWRN_NOT_FOUND;
     629    if (!pszCacheSubDir || !*pszCacheSubDir)
     630        return VWRN_NOT_FOUND;
    628631
    629632    /*
     
    749752                                   const char *pszCacheSubDir, PRTPATHSPLIT pSplitFn)
    750753{
     754    if (!pszCacheSubDir || !*pszCacheSubDir)
     755        return VINF_SUCCESS;
     756
    751757    /** @todo copy to cache */
    752758    return VINF_SUCCESS;
     
    10021008    if (RT_FAILURE(rc2))
    10031009        return rc2;
     1010    AssertReturnStmt(pSplitFn->fProps & RTPATH_PROP_FILENAME, RTPathSplitFree(pSplitFn), VERR_IS_A_DIRECTORY);
    10041011
    10051012    /*
     
    10141021            RTPathChangeToUnixSlashes(szPath, false);
    10151022            rtDbgCfgLog1(pThis, "Trying '%s'...\n", szPath);
    1016             rc2 = pfnCallback(pThis, pszFilename, pvUser1, pvUser2);
     1023            rc2 = pfnCallback(pThis, szPath, pvUser1, pvUser2);
    10171024            if (rc2 == VINF_CALLBACK_RETURN)
    10181025                rtDbgCfgLog1(pThis, "Found '%s'.\n", szPath);
     
    11681175                                  pfnCallback, pvUser1, pvUser2);
    11691176}
     1177
     1178
     1179
     1180/*
     1181 *
     1182 *  D a r w i n   . d S Y M   b u n d l e s
     1183 *  D a r w i n   . d S Y M   b u n d l e s
     1184 *  D a r w i n   . d S Y M   b u n d l e s
     1185 *
     1186 */
     1187
     1188/**
     1189 * Very similar to rtDbgCfgTryOpenDir.
     1190 */
     1191static int rtDbgCfgTryOpenDsymBundleInDir(PRTDBGCFGINT pThis, char *pszPath, PRTPATHSPLIT pSplitFn, const char *pszDsymName,
     1192                                          uint32_t fFlags, PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2)
     1193{
     1194    int rcRet = VWRN_NOT_FOUND;
     1195    int rc2;
     1196
     1197    /* If the directory doesn't exist, just quit immediately.
     1198       Note! Our case insensitivity doesn't extend to the search dirs themselfs,
     1199             only to the bits under neath them. */
     1200    if (!RTDirExists(pszPath))
     1201    {
     1202        rtDbgCfgLog2(pThis, "Dir does not exist: '%s'\n", pszPath);
     1203        return rcRet;
     1204    }
     1205
     1206    /* Figure out whether we have to do a case sensitive search or not.
     1207       Note! As a simplification, we don't ask for case settings in each
     1208             directory under the user specified path, we assume the file
     1209             systems that mounted there have compatible settings. Faster
     1210             that way. */
     1211    bool const fCaseInsensitive = (fFlags & RTDBGCFG_O_CASE_INSENSITIVE)
     1212                               && !rtDbgCfgIsFsCaseInsensitive(pszPath);
     1213
     1214    size_t const cchPath = strlen(pszPath);
     1215
     1216    /*
     1217     * Look for the file with less and less of the original path given.
     1218     */
     1219    for (unsigned i = RTPATH_PROP_HAS_ROOT_SPEC(pSplitFn->fProps); i < pSplitFn->cComps; i++)
     1220    {
     1221        pszPath[cchPath] = '\0';
     1222
     1223        rc2 = VINF_SUCCESS;
     1224        for (unsigned j = i; j < pSplitFn->cComps - 1U && RT_SUCCESS(rc2); j++)
     1225            if (!rtDbgCfgIsDirAndFixCase(pszPath, pSplitFn->apszComps[i], fCaseInsensitive))
     1226                rc2 = VERR_FILE_NOT_FOUND;
     1227        if (    RT_SUCCESS(rc2)
     1228            && !rtDbgCfgIsDirAndFixCase(pszPath, pszDsymName, fCaseInsensitive)
     1229            && !rtDbgCfgIsDirAndFixCase(pszPath, "Contents", fCaseInsensitive)
     1230            && !rtDbgCfgIsDirAndFixCase(pszPath, "Resources", fCaseInsensitive)
     1231            && !rtDbgCfgIsDirAndFixCase(pszPath, "DWARF", fCaseInsensitive))
     1232        {
     1233            if (rtDbgCfgIsFileAndFixCase(pszPath, pSplitFn->apszComps[pSplitFn->cComps - 1], fCaseInsensitive, false, NULL))
     1234            {
     1235                rtDbgCfgLog1(pThis, "Trying '%s'...\n", pszPath);
     1236                rc2 = pfnCallback(pThis, pszPath, pvUser1, pvUser2);
     1237                if (rc2 == VINF_CALLBACK_RETURN || rc2 == VERR_CALLBACK_RETURN)
     1238                {
     1239                    if (rc2 == VINF_CALLBACK_RETURN)
     1240                        rtDbgCfgLog1(pThis, "Found '%s'.\n", pszPath);
     1241                    else
     1242                        rtDbgCfgLog1(pThis, "Error opening '%s'.\n", pszPath);
     1243                    return rc2;
     1244                }
     1245                rtDbgCfgLog1(pThis, "Error %Rrc opening '%s'.\n", rc2, pszPath);
     1246                if (RT_FAILURE(rc2) && RT_SUCCESS_NP(rcRet))
     1247                    rcRet = rc2;
     1248            }
     1249        }
     1250        rc2 = VERR_FILE_NOT_FOUND;
     1251    }
     1252
     1253    /*
     1254     * Do a recursive search if requested.
     1255     */
     1256    if (   (fFlags & RTDBGCFG_O_RECURSIVE)
     1257        && !(pThis->fFlags & RTDBGCFG_FLAGS_NO_RECURSIV_SEARCH) )
     1258    {
     1259        /** @todo Recursive searching will be done later. */
     1260    }
     1261
     1262    return rcRet;
     1263}
     1264
     1265
     1266/**
     1267 * Very similar to rtDbgCfgTryOpenList.
     1268 */
     1269static int rtDbgCfgTryOpenDsumBundleInList(PRTDBGCFGINT pThis, PRTLISTANCHOR pList, PRTPATHSPLIT pSplitFn,
     1270                                           const char *pszDsymName, const char *pszCacheSubDir, uint32_t fFlags, char *pszPath,
     1271                                           PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2)
     1272{
     1273    int rcRet = VWRN_NOT_FOUND;
     1274    int rc2;
     1275
     1276    const char *pchCache = NULL;
     1277    size_t      cchCache = 0;
     1278    int         rcCache  = VWRN_NOT_FOUND;
     1279
     1280    PRTDBGCFGSTR pCur;
     1281    RTListForEach(pList, pCur, RTDBGCFGSTR, ListEntry)
     1282    {
     1283        size_t      cchDir = pCur->cch;
     1284        const char *pszDir = pCur->sz;
     1285        rtDbgCfgLog2(pThis, "Path list entry: '%s'\n", pszDir);
     1286
     1287        /* This is very simplistic, but we have a unreasonably large path
     1288           buffer, so it'll work just fine and simplify things greatly below. */
     1289        if (cchDir >= RTPATH_MAX - 8U)
     1290        {
     1291            if (RT_SUCCESS_NP(rcRet))
     1292                rcRet = VERR_FILENAME_TOO_LONG;
     1293            continue;
     1294        }
     1295
     1296        /*
     1297         * Process the path according to it's type.
     1298         */
     1299        if (!strncmp(pszDir, RT_STR_TUPLE("srv*")))
     1300        {
     1301            /*
     1302             * Symbol server.
     1303             */
     1304            pszDir += sizeof("srv*") - 1;
     1305            cchDir -= sizeof("srv*") - 1;
     1306            bool        fSearchCache = false;
     1307            const char *pszServer = (const char *)memchr(pszDir, '*', cchDir);
     1308            if (!pszServer)
     1309                pszServer = pszDir;
     1310            else if (pszServer == pszDir)
     1311                continue;
     1312            {
     1313                fSearchCache = true;
     1314                pchCache = pszDir;
     1315                cchCache = pszServer - pszDir;
     1316                pszServer++;
     1317            }
     1318
     1319            /* We don't have any default cache directory, so skip if the cache is missing. */
     1320            if (cchCache == 0)
     1321                continue;
     1322
     1323            /* Search the cache first (if we haven't already done so). */
     1324            if (fSearchCache)
     1325            {
     1326                memcpy(pszPath, pchCache, cchCache);
     1327                pszPath[cchCache] = '\0';
     1328                RTPathChangeToUnixSlashes(pszPath, false);
     1329
     1330                rcCache = rc2 = rtDbgCfgTryOpenCache(pThis, pszPath, pszCacheSubDir, pSplitFn, fFlags,
     1331                                                     pfnCallback, pvUser1, pvUser2);
     1332                if (rc2 == VINF_CALLBACK_RETURN || rc2 == VERR_CALLBACK_RETURN)
     1333                    return rc2;
     1334            }
     1335
     1336            /* Try downloading the file. */
     1337            if (rcCache == VWRN_NOT_FOUND)
     1338            {
     1339                memcpy(pszPath, pchCache, cchCache);
     1340                pszPath[cchCache] = '\0';
     1341                RTPathChangeToUnixSlashes(pszPath, false);
     1342
     1343                rc2 = rtDbgCfgTryDownloadAndOpen(pThis, pszServer, pszPath, pszCacheSubDir, pSplitFn, fFlags,
     1344                                                 pfnCallback, pvUser1, pvUser2);
     1345                if (rc2 == VINF_CALLBACK_RETURN || rc2 == VERR_CALLBACK_RETURN)
     1346                    return rc2;
     1347            }
     1348        }
     1349        else if (!strncmp(pszDir, RT_STR_TUPLE("cache*")))
     1350        {
     1351            /*
     1352             * Cache directory.
     1353             */
     1354            pszDir += sizeof("cache*") - 1;
     1355            cchDir -= sizeof("cache*") - 1;
     1356            if (!cchDir)
     1357                continue;
     1358            pchCache = pszDir;
     1359            cchCache = cchDir;
     1360
     1361            memcpy(pszPath, pchCache, cchCache);
     1362            pszPath[cchCache] = '\0';
     1363            RTPathChangeToUnixSlashes(pszPath, false);
     1364
     1365            rcCache = rc2 = rtDbgCfgTryOpenCache(pThis, pszPath, pszCacheSubDir, pSplitFn, fFlags,
     1366                                                 pfnCallback, pvUser1, pvUser2);
     1367            if (rc2 == VINF_CALLBACK_RETURN || rc2 == VERR_CALLBACK_RETURN)
     1368                return rc2;
     1369        }
     1370        else
     1371        {
     1372            /*
     1373             * Normal directory. Check for our own 'rec*' and 'norec*' prefix
     1374             * flags governing recursive searching.
     1375             */
     1376            uint32_t fFlagsDir = fFlags;
     1377            if (!strncmp(pszDir, RT_STR_TUPLE("rec*")))
     1378            {
     1379                pszDir += sizeof("rec*") - 1;
     1380                cchDir -= sizeof("rec*") - 1;
     1381                fFlagsDir |= RTDBGCFG_O_RECURSIVE;
     1382            }
     1383            else if (!strncmp(pszDir, RT_STR_TUPLE("norec*")))
     1384            {
     1385                pszDir += sizeof("norec*") - 1;
     1386                cchDir -= sizeof("norec*") - 1;
     1387                fFlagsDir &= ~RTDBGCFG_O_RECURSIVE;
     1388            }
     1389
     1390            /* Copy the path into the buffer and do the searching. */
     1391            memcpy(pszPath, pszDir, cchDir);
     1392            pszPath[cchDir] = '\0';
     1393            RTPathChangeToUnixSlashes(pszPath, false);
     1394
     1395            rc2 = rtDbgCfgTryOpenDsymBundleInDir(pThis, pszPath, pSplitFn, pszDsymName, fFlagsDir,
     1396                                                 pfnCallback, pvUser1, pvUser2);
     1397            if (rc2 == VINF_CALLBACK_RETURN || rc2 == VERR_CALLBACK_RETURN)
     1398            {
     1399                if (   rc2 == VINF_CALLBACK_RETURN
     1400                    && cchCache > 0)
     1401                    rtDbgCfgCopyFileToCache(pThis, pszPath, pchCache, cchCache, pszCacheSubDir, pSplitFn);
     1402                return rc2;
     1403            }
     1404        }
     1405
     1406        /* Propagate errors. */
     1407        if (RT_FAILURE(rc2) && RT_SUCCESS_NP(rcRet))
     1408            rcRet = rc2;
     1409    }
     1410
     1411    return rcRet;
     1412}
     1413
     1414
     1415RTDECL(int) RTDbgCfgOpenDsymBundle(RTDBGCFG hDbgCfg, const char *pszImage, PCRTUUID pUuid,
     1416                                   PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2)
     1417{
     1418    /*
     1419     * Bundles are directories, means we can forget about sharing code much
     1420     * with the other RTDbgCfgOpenXXX methods.  Thus we're duplicating a lot of
     1421     * code from rtDbgCfgOpenWithSubDir with .dSYM related adjustments, so, a bug
     1422     * found here or there probably means the other version needs updating.
     1423     */
     1424    int rcRet = VINF_SUCCESS;
     1425    int rc2;
     1426
     1427    //RTStrPrintf(szFile, sizeof(szFile), "%s.dSYM/Contents/Resources/DWARF/%s", pszFilename, pszFilename);
     1428
     1429    /*
     1430     * Do a little validating first.
     1431     */
     1432    PRTDBGCFGINT pThis = hDbgCfg;
     1433    if (pThis != NIL_RTDBGCFG)
     1434        RTDBGCFG_VALID_RETURN_RC(pThis, VERR_INVALID_HANDLE);
     1435    else
     1436        pThis = NULL;
     1437    AssertPtrReturn(pszImage, VERR_INVALID_POINTER);
     1438    AssertPtrReturn(pfnCallback, VERR_INVALID_POINTER);
     1439
     1440    /*
     1441     * Set up rtDbgCfgOpenWithSubDir parameters.
     1442     */
     1443    uint32_t fFlags = RTDBGCFG_O_EXT_DEBUG_FILE | RT_OPSYS_DARWIN;
     1444    const char *pszCacheSubDir = NULL;
     1445    char szCacheSubDir[RTUUID_STR_LENGTH];
     1446    if (pUuid)
     1447    {
     1448        RTUuidToStr(pUuid, szCacheSubDir, sizeof(szCacheSubDir));
     1449        pszCacheSubDir = szCacheSubDir;
     1450    }
     1451
     1452    /*
     1453     * Do some guessing as to the way we should parse the filename and whether
     1454     * it's case exact or not.
     1455     */
     1456    bool fDosPath = strchr(pszImage, ':')  != NULL
     1457                 || strchr(pszImage, '\\') != NULL
     1458                 || RT_OPSYS_USES_DOS_PATHS(fFlags & RTDBGCFG_O_OPSYS_MASK)
     1459                 || (fFlags & RTDBGCFG_O_CASE_INSENSITIVE);
     1460    if (fDosPath)
     1461        fFlags |= RTDBGCFG_O_CASE_INSENSITIVE;
     1462
     1463    rtDbgCfgLog2(pThis, "Looking for '%s' with %#x flags...\n", pszImage, fFlags);
     1464
     1465    PRTPATHSPLIT pSplitFn;
     1466    rc2 = RTPathSplitA(pszImage, &pSplitFn, fDosPath ? RTPATH_STR_F_STYLE_DOS : RTPATH_STR_F_STYLE_UNIX);
     1467    if (RT_FAILURE(rc2))
     1468        return rc2;
     1469    AssertReturnStmt(pSplitFn->fProps & RTPATH_PROP_FILENAME, RTPathSplitFree(pSplitFn), VERR_IS_A_DIRECTORY);
     1470
     1471    /*
     1472     * Try the image directory first.
     1473     */
     1474    char szPath[RTPATH_MAX];
     1475    if (pSplitFn->cComps > 0)
     1476    {
     1477        rc2 = RTPathSplitReassemble(pSplitFn, RTPATH_STR_F_STYLE_HOST, szPath, sizeof(szPath));
     1478        if (RT_SUCCESS(rc2))
     1479            rc2 = RTStrCat(szPath, sizeof(szPath),
     1480                           ".dSYM" RTPATH_SLASH_STR "Contents" RTPATH_SLASH_STR "Resources" RTPATH_SLASH_STR "DWARF");
     1481        if (RT_SUCCESS(rc2))
     1482            rc2 = RTPathAppend(szPath, sizeof(szPath), pSplitFn->apszComps[pSplitFn->cComps - 1]);
     1483        if (RT_SUCCESS(rc2))
     1484        {
     1485            RTPathChangeToUnixSlashes(szPath, false);
     1486            rtDbgCfgLog1(pThis, "Trying '%s'...\n", szPath);
     1487            rc2 = pfnCallback(pThis, szPath, pvUser1, pvUser2);
     1488            if (rc2 == VINF_CALLBACK_RETURN)
     1489                rtDbgCfgLog1(pThis, "Found '%s'.\n", szPath);
     1490            else if (rc2 == VERR_CALLBACK_RETURN)
     1491                rtDbgCfgLog1(pThis, "Error opening '%s'.\n", szPath);
     1492            else
     1493                rtDbgCfgLog1(pThis, "Error %Rrc opening '%s'.\n", rc2, szPath);
     1494        }
     1495    }
     1496    if (   rc2 != VINF_CALLBACK_RETURN
     1497        && rc2 != VERR_CALLBACK_RETURN)
     1498    {
     1499        char *pszDsymName = (char *)alloca(strlen(pSplitFn->apszComps[pSplitFn->cComps - 1]) + sizeof(".dSYM"));
     1500        strcat(strcpy(pszDsymName, pSplitFn->apszComps[pSplitFn->cComps - 1]), ".dSYM");
     1501
     1502        /*
     1503         * Try the current directory (will take cover relative paths
     1504         * skipped above).
     1505         */
     1506        rc2 = RTPathGetCurrent(szPath, sizeof(szPath));
     1507        if (RT_FAILURE(rc2))
     1508            strcpy(szPath, ".");
     1509        RTPathChangeToUnixSlashes(szPath, false);
     1510
     1511        rc2 = rtDbgCfgTryOpenDsymBundleInDir(pThis, szPath, pSplitFn, pszDsymName, fFlags, pfnCallback, pvUser1, pvUser2);
     1512        if (RT_FAILURE(rc2) && RT_SUCCESS_NP(rcRet))
     1513            rcRet = rc2;
     1514
     1515        if (   rc2 != VINF_CALLBACK_RETURN
     1516            && rc2 != VERR_CALLBACK_RETURN
     1517            && pThis)
     1518        {
     1519            rc2 = RTCritSectRwEnterShared(&pThis->CritSect);
     1520            if (RT_SUCCESS(rc2))
     1521            {
     1522                /*
     1523                 * Run the applicable lists.
     1524                 */
     1525                rc2 = rtDbgCfgTryOpenDsumBundleInList(pThis, &pThis->PathList, pSplitFn, pszDsymName,
     1526                                                      pszCacheSubDir, fFlags, szPath,
     1527                                                      pfnCallback, pvUser1, pvUser2);
     1528                if (RT_FAILURE(rc2) && RT_SUCCESS_NP(rcRet))
     1529                    rcRet = rc2;
     1530
     1531                RTCritSectRwLeaveShared(&pThis->CritSect);
     1532            }
     1533            else if (RT_SUCCESS(rcRet))
     1534                rcRet = rc2;
     1535        }
     1536    }
     1537
     1538    RTPathSplitFree(pSplitFn);
     1539    if (   rc2 == VINF_CALLBACK_RETURN
     1540        || rc2 == VERR_CALLBACK_RETURN)
     1541        rcRet = rc2;
     1542    else if (RT_SUCCESS(rcRet))
     1543        rcRet = VERR_NOT_FOUND;
     1544    return rcRet;
     1545
     1546
     1547}
     1548
    11701549
    11711550
  • trunk/src/VBox/Runtime/common/dbg/dbgmod.cpp

    r46134 r46161  
    123123
    124124
     125
     126
    125127/**
    126128 * Cleanup debug info interpreter globals.
     
    359361}
    360362RT_EXPORT_SYMBOL(RTDbgModCreate);
    361 
    362 
    363 RTDECL(int) RTDbgModCreateFromImage(PRTDBGMOD phDbgMod, const char *pszFilename, const char *pszName, RTDBGCFG hDbgCfg)
    364 {
    365     /*
    366      * Input validation and lazy initialization.
    367      */
    368     AssertPtrReturn(phDbgMod, VERR_INVALID_POINTER);
    369     *phDbgMod = NIL_RTDBGMOD;
    370     AssertPtrReturn(pszFilename, VERR_INVALID_POINTER);
    371     AssertReturn(*pszFilename, VERR_INVALID_PARAMETER);
    372     AssertPtrNullReturn(pszName, VERR_INVALID_POINTER);
    373 
    374     int rc = rtDbgModLazyInit();
    375     if (RT_FAILURE(rc))
    376         return rc;
    377 
    378     if (!pszName)
    379         pszName = RTPathFilenameEx(pszFilename, RTPATH_STR_F_STYLE_DOS);
    380 
    381     /*
    382      * Allocate a new module instance.
    383      */
    384     PRTDBGMODINT pDbgMod = (PRTDBGMODINT)RTMemAllocZ(sizeof(*pDbgMod));
    385     if (!pDbgMod)
    386         return VERR_NO_MEMORY;
    387     pDbgMod->u32Magic = RTDBGMOD_MAGIC;
    388     pDbgMod->cRefs = 1;
    389     rc = RTCritSectInit(&pDbgMod->CritSect);
    390     if (RT_SUCCESS(rc))
    391     {
    392         pDbgMod->pszName = RTStrCacheEnterLower(g_hDbgModStrCache, pszName);
    393         if (pDbgMod->pszName)
    394         {
    395             pDbgMod->pszImgFile = RTStrCacheEnter(g_hDbgModStrCache, pszFilename);
    396             if (pDbgMod->pszImgFile)
    397             {
    398                 RTStrCacheRetain(pDbgMod->pszImgFile);
    399                 pDbgMod->pszImgFileSpecified = pDbgMod->pszImgFile;
    400 
    401                 /*
    402                  * Find an image reader which groks the file.
    403                  */
    404                 rc = RTSemRWRequestRead(g_hDbgModRWSem, RT_INDEFINITE_WAIT);
    405                 if (RT_SUCCESS(rc))
    406                 {
    407                     rc = VERR_DBG_NO_MATCHING_INTERPRETER;
    408                     PRTDBGMODREGIMG pImg;
    409                     for (pImg = g_pImgHead; pImg; pImg = pImg->pNext)
    410                     {
    411                         pDbgMod->pImgVt    = pImg->pVt;
    412                         pDbgMod->pvImgPriv = NULL;
    413                         rc = pImg->pVt->pfnTryOpen(pDbgMod);
    414                         if (RT_SUCCESS(rc))
    415                         {
    416                             /*
    417                              * Find a debug info interpreter.
    418                              */
    419                             rc = VERR_DBG_NO_MATCHING_INTERPRETER;
    420                             for (PRTDBGMODREGDBG pDbg = g_pDbgHead; pDbg; pDbg = pDbg->pNext)
    421                             {
    422                                 pDbgMod->pDbgVt = pDbg->pVt;
    423                                 pDbgMod->pvDbgPriv = NULL;
    424                                 rc = pDbg->pVt->pfnTryOpen(pDbgMod);
    425                                 if (RT_SUCCESS(rc))
    426                                 {
    427                                     /*
    428                                      * That's it!
    429                                      */
    430                                     ASMAtomicIncU32(&pDbg->cUsers);
    431                                     ASMAtomicIncU32(&pImg->cUsers);
    432                                     RTSemRWReleaseRead(g_hDbgModRWSem);
    433 
    434                                     *phDbgMod = pDbgMod;
    435                                     return rc;
    436                                 }
    437                             }
    438 
    439                             /*
    440                              * Image detected, but found no debug info we were
    441                              * able to understand.
    442                              */
    443                             /** @todo Fall back on exported symbols! */
    444                             pDbgMod->pImgVt->pfnClose(pDbgMod);
    445                             break;
    446                         }
    447                     }
    448 
    449                     /*
    450                      * Could it be a file containing raw debug info?
    451                      */
    452                     if (!pImg)
    453                     {
    454                         pDbgMod->pImgVt     = NULL;
    455                         pDbgMod->pvImgPriv  = NULL;
    456                         pDbgMod->pszDbgFile = pDbgMod->pszImgFile;
    457                         pDbgMod->pszImgFile = NULL;
    458 
    459                         for (PRTDBGMODREGDBG pDbg = g_pDbgHead; pDbg; pDbg = pDbg->pNext)
    460                         {
    461                             pDbgMod->pDbgVt = pDbg->pVt;
    462                             pDbgMod->pvDbgPriv = NULL;
    463                             rc = pDbg->pVt->pfnTryOpen(pDbgMod);
    464                             if (RT_SUCCESS(rc))
    465                             {
    466                                 /*
    467                                  * That's it!
    468                                  */
    469                                 ASMAtomicIncU32(&pDbg->cUsers);
    470                                 RTSemRWReleaseRead(g_hDbgModRWSem);
    471 
    472                                 *phDbgMod = pDbgMod;
    473                                 return rc;
    474                             }
    475                         }
    476 
    477                         pDbgMod->pszImgFile = pDbgMod->pszDbgFile;
    478                         pDbgMod->pszDbgFile = NULL;
    479                     }
    480 
    481                     /* bail out */
    482                     RTSemRWReleaseRead(g_hDbgModRWSem);
    483                 }
    484                 RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFileSpecified);
    485                 RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFile);
    486             }
    487             else
    488                 rc = VERR_NO_STR_MEMORY;
    489             RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszName);
    490         }
    491         else
    492             rc = VERR_NO_STR_MEMORY;
    493         RTCritSectDelete(&pDbgMod->CritSect);
    494     }
    495 
    496     RTMemFree(pDbgMod);
    497     return rc;
    498 }
    499 RT_EXPORT_SYMBOL(RTDbgModCreateFromImage);
    500 
    501363
    502364
     
    584446
    585447
    586 
    587448/*
    588449 *
    589  *  P E   I M A G E
    590  *  P E   I M A G E
    591  *  P E   I M A G E
     450 *  E x e c u t a b l e   I m a g e   F i l e s
     451 *  E x e c u t a b l e   I m a g e   F i l e s
     452 *  E x e c u t a b l e   I m a g e   F i l e s
    592453 *
    593454 */
     
    804665
    805666
     667/** @callback_method_impl{FNRTDBGCFGOPEN} */
     668static DECLCALLBACK(int) rtDbgModExtDbgInfoOpenCallback2(RTDBGCFG hDbgCfg, const char *pszFilename, void *pvUser1, void *pvUser2)
     669{
     670    PRTDBGMODINT        pDbgMod   = (PRTDBGMODINT)pvUser1;
     671    NOREF(pvUser2); /** @todo image matching string or smth. */
     672
     673    Assert(!pDbgMod->pDbgVt);
     674    Assert(!pDbgMod->pvDbgPriv);
     675    Assert(!pDbgMod->pszDbgFile);
     676
     677    /*
     678     * Set the debug file name and try possible interpreters.
     679     */
     680    pDbgMod->pszDbgFile = RTStrCacheEnter(g_hDbgModStrCache, pszFilename);
     681
     682    int rc = RTSemRWRequestRead(g_hDbgModRWSem, RT_INDEFINITE_WAIT);
     683    if (RT_SUCCESS(rc))
     684    {
     685        for (PRTDBGMODREGDBG pDbg = g_pDbgHead; pDbg; pDbg = pDbg->pNext)
     686        {
     687            pDbgMod->pDbgVt    = pDbg->pVt;
     688            pDbgMod->pvDbgPriv = NULL;
     689            rc = pDbg->pVt->pfnTryOpen(pDbgMod);
     690            if (RT_SUCCESS(rc))
     691            {
     692                /*
     693                 * Got it!
     694                 */
     695                ASMAtomicIncU32(&pDbg->cUsers);
     696                RTSemRWReleaseRead(g_hDbgModRWSem);
     697                return VINF_CALLBACK_RETURN;
     698            }
     699            pDbgMod->pDbgVt    = NULL;
     700            Assert(pDbgMod->pvDbgPriv == NULL);
     701        }
     702    }
     703
     704    /* No joy. */
     705    RTSemRWReleaseRead(g_hDbgModRWSem);
     706    RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszDbgFile);
     707    pDbgMod->pszDbgFile = NULL;
     708    return rc;
     709}
     710
     711
     712/**
     713 * Opens external debug info that is not listed in the image.
     714 *
     715 * @returns IPRT status code
     716 * @param   pDbgMod             The debug module.
     717 * @param   hDbgCfg             The debug config.  Can be NIL.
     718 */
     719static int rtDbgModOpenDebugInfoExternalToImage2(PRTDBGMODINT pDbgMod, RTDBGCFG hDbgCfg)
     720{
     721    int rc;
     722    Assert(!pDbgMod->pDbgVt);
     723    Assert(pDbgMod->pImgVt);
     724
     725    /*
     726     * Figure out what to search for based on the image format.
     727     */
     728    const char *pszzExts = NULL;
     729    RTLDRFMT    enmFmt = pDbgMod->pImgVt->pfnGetFormat(pDbgMod);
     730    switch (enmFmt)
     731    {
     732        case RTLDRFMT_MACHO:
     733        {
     734            rc = RTDbgCfgOpenDsymBundle(hDbgCfg, pDbgMod->pszImgFile, NULL /**@todo pUuid*/,
     735                                        rtDbgModExtDbgInfoOpenCallback2, pDbgMod, NULL /*pvUser2*/);
     736            if (RT_SUCCESS(rc))
     737                return VINF_SUCCESS;
     738            break;
     739        }
     740
     741#if 0 /* Will be links in the image if these apply. .map readers for PE or ELF we don't have. */
     742        case RTLDRFMT_ELF:
     743            pszzExts = ".debug\0.dwo\0";
     744            break;
     745        case RTLDRFMT_PE:
     746            pszzExts = ".map\0";
     747            break;
     748#endif
     749#if 0 /* Haven't implemented .sym or .map file readers for OS/2 yet. */
     750        case RTLDRFMT_LX:
     751            pszzExts = ".sym\0.map\0";
     752            break;
     753#endif
     754        default:
     755            break;
     756    }
     757
     758    NOREF(pszzExts);
     759#if 0 /* Later */
     760    if (pszzExts)
     761    {
     762
     763    }
     764#endif
     765
     766    LogFlow(("rtDbgModOpenDebugInfoExternalToImage2: rc=%Rrc\n", rc));
     767    return VERR_NOT_FOUND;
     768}
     769
     770
     771RTDECL(int) RTDbgModCreateFromImage(PRTDBGMOD phDbgMod, const char *pszFilename, const char *pszName,
     772                                    RTLDRARCH enmArch, RTDBGCFG hDbgCfg)
     773{
     774    /*
     775     * Input validation and lazy initialization.
     776     */
     777    AssertPtrReturn(phDbgMod, VERR_INVALID_POINTER);
     778    *phDbgMod = NIL_RTDBGMOD;
     779    AssertPtrReturn(pszFilename, VERR_INVALID_POINTER);
     780    AssertReturn(*pszFilename, VERR_INVALID_PARAMETER);
     781    AssertPtrNullReturn(pszName, VERR_INVALID_POINTER);
     782    AssertReturn(enmArch > RTLDRARCH_INVALID && enmArch < RTLDRARCH_END, VERR_INVALID_PARAMETER);
     783
     784    int rc = rtDbgModLazyInit();
     785    if (RT_FAILURE(rc))
     786        return rc;
     787
     788    if (!pszName)
     789        pszName = RTPathFilenameEx(pszFilename, RTPATH_STR_F_STYLE_DOS);
     790
     791    /*
     792     * Allocate a new module instance.
     793     */
     794    PRTDBGMODINT pDbgMod = (PRTDBGMODINT)RTMemAllocZ(sizeof(*pDbgMod));
     795    if (!pDbgMod)
     796        return VERR_NO_MEMORY;
     797    pDbgMod->u32Magic = RTDBGMOD_MAGIC;
     798    pDbgMod->cRefs = 1;
     799    rc = RTCritSectInit(&pDbgMod->CritSect);
     800    if (RT_SUCCESS(rc))
     801    {
     802        pDbgMod->pszName = RTStrCacheEnterLower(g_hDbgModStrCache, pszName);
     803        if (pDbgMod->pszName)
     804        {
     805            pDbgMod->pszImgFile = RTStrCacheEnter(g_hDbgModStrCache, pszFilename);
     806            if (pDbgMod->pszImgFile)
     807            {
     808                RTStrCacheRetain(pDbgMod->pszImgFile);
     809                pDbgMod->pszImgFileSpecified = pDbgMod->pszImgFile;
     810
     811                /*
     812                 * Find an image reader which groks the file.
     813                 */
     814                rc = RTSemRWRequestRead(g_hDbgModRWSem, RT_INDEFINITE_WAIT);
     815                if (RT_SUCCESS(rc))
     816                {
     817                    rc = VERR_DBG_NO_MATCHING_INTERPRETER;
     818                    PRTDBGMODREGIMG pImg;
     819                    for (pImg = g_pImgHead; pImg; pImg = pImg->pNext)
     820                    {
     821                        pDbgMod->pImgVt    = pImg->pVt;
     822                        pDbgMod->pvImgPriv = NULL;
     823                        /** @todo need to specify some arch stuff here. */
     824                        rc = pImg->pVt->pfnTryOpen(pDbgMod, enmArch);
     825                        if (RT_SUCCESS(rc))
     826                        {
     827                            /*
     828                             * Image detected, but found no debug info we were
     829                             * able to understand.
     830                             */
     831                            /** @todo some generic way of matching image and debug info, flexible signature
     832                             *        of some kind. Apple uses UUIDs, microsoft uses a UUID+age or a
     833                             *        size+timestamp, and GNU a CRC32 (last time I checked). */
     834                            rc = rtDbgModOpenDebugInfoExternalToImage(pDbgMod, hDbgCfg);
     835                            if (RT_FAILURE(rc))
     836                                rc = rtDbgModOpenDebugInfoInsideImage(pDbgMod);
     837                            if (RT_FAILURE(rc))
     838                                rc = rtDbgModOpenDebugInfoExternalToImage2(pDbgMod, hDbgCfg);
     839                            if (RT_FAILURE(rc))
     840                                rc = rtDbgModCreateForExports(pDbgMod);
     841                            if (RT_SUCCESS(rc))
     842                            {
     843                                *phDbgMod = pDbgMod;
     844                                return VINF_SUCCESS;
     845                            }
     846
     847                            /* Failed, close up the shop. */
     848                            pDbgMod->pImgVt->pfnClose(pDbgMod);
     849                            pDbgMod->pImgVt = NULL;
     850                            pDbgMod->pvImgPriv = NULL;
     851                            break;
     852                        }
     853                    }
     854
     855                    /*
     856                     * Could it be a file containing raw debug info?
     857                     */
     858                    if (!pImg)
     859                    {
     860                        pDbgMod->pImgVt     = NULL;
     861                        pDbgMod->pvImgPriv  = NULL;
     862                        pDbgMod->pszDbgFile = pDbgMod->pszImgFile;
     863                        pDbgMod->pszImgFile = NULL;
     864
     865                        for (PRTDBGMODREGDBG pDbg = g_pDbgHead; pDbg; pDbg = pDbg->pNext)
     866                        {
     867                            pDbgMod->pDbgVt = pDbg->pVt;
     868                            pDbgMod->pvDbgPriv = NULL;
     869                            rc = pDbg->pVt->pfnTryOpen(pDbgMod);
     870                            if (RT_SUCCESS(rc))
     871                            {
     872                                /*
     873                                 * That's it!
     874                                 */
     875                                ASMAtomicIncU32(&pDbg->cUsers);
     876                                RTSemRWReleaseRead(g_hDbgModRWSem);
     877
     878                                *phDbgMod = pDbgMod;
     879                                return rc;
     880                            }
     881                        }
     882
     883                        pDbgMod->pszImgFile = pDbgMod->pszDbgFile;
     884                        pDbgMod->pszDbgFile = NULL;
     885                    }
     886
     887                    /* bail out */
     888                    RTSemRWReleaseRead(g_hDbgModRWSem);
     889                }
     890                RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFileSpecified);
     891                RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFile);
     892            }
     893            else
     894                rc = VERR_NO_STR_MEMORY;
     895            RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszName);
     896        }
     897        else
     898            rc = VERR_NO_STR_MEMORY;
     899        RTCritSectDelete(&pDbgMod->CritSect);
     900    }
     901
     902    RTMemFree(pDbgMod);
     903    return rc;
     904}
     905RT_EXPORT_SYMBOL(RTDbgModCreateFromImage);
     906
     907
     908
     909
     910
     911/*
     912 *
     913 *  P E   I M A G E
     914 *  P E   I M A G E
     915 *  P E   I M A G E
     916 *
     917 */
     918
     919
    806920
    807921/** @callback_method_impl{FNRTDBGCFGOPEN} */
     
    838952            pDbgMod->pImgVt    = pImg->pVt;
    839953            pDbgMod->pvImgPriv = NULL;
    840             rc = pImg->pVt->pfnTryOpen(pDbgMod);
     954            rc = pImg->pVt->pfnTryOpen(pDbgMod, RTLDRARCH_WHATEVER);
    841955            if (RT_SUCCESS(rc))
    842956                break;
     
    10401154    return rc;
    10411155}
    1042 RT_EXPORT_SYMBOL(RTDbgModCreateFromImage);
     1156RT_EXPORT_SYMBOL(RTDbgModCreateFromPeImage);
    10431157
    10441158
  • trunk/src/VBox/Runtime/common/dbg/dbgmoddeferred.cpp

    r46149 r46161  
    440440
    441441
     442/** @interface_method_impl{RTDBGMODVTIMG,pfnGetFormat} */
     443static DECLCALLBACK(RTLDRFMT) rtDbgModDeferredImg_GetFormat(PRTDBGMODINT pMod)
     444{
     445    RTLDRFMT enmFmt;
     446    int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
     447    if (RT_SUCCESS(rc))
     448        enmFmt = pMod->pImgVt->pfnGetFormat(pMod);
     449    else
     450        enmFmt = RTLDRFMT_INVALID;
     451    return enmFmt;
     452}
     453
     454
    442455/** @interface_method_impl{RTDBGMODVTIMG,pfnUnmapPart} */
    443456static DECLCALLBACK(int) rtDbgModDeferredImg_UnmapPart(PRTDBGMODINT pMod, size_t cb, void const **ppvMap)
     
    530543
    531544/** @interface_method_impl{RTDBGMODVTIMG,pfnTryOpen} */
    532 static DECLCALLBACK(int) rtDbgModDeferredImg_TryOpen(PRTDBGMODINT pMod)
    533 {
     545static DECLCALLBACK(int) rtDbgModDeferredImg_TryOpen(PRTDBGMODINT pMod, RTLDRARCH enmArch)
     546{
     547    NOREF(enmArch);
    534548    return rtDbgModDeferredDoIt(pMod, true /*fForceRetry*/);
    535549}
     
    552566    /*.pfnMapPart = */                  rtDbgModDeferredImg_MapPart,
    553567    /*.pfnUnmapPart = */                rtDbgModDeferredImg_UnmapPart,
     568    /*.pfnGetFormat = */                rtDbgModDeferredImg_GetFormat,
    554569
    555570    /*.u32EndMagic = */                 RTDBGMODVTIMG_MAGIC
  • trunk/src/VBox/Runtime/common/dbg/dbgmodldr.cpp

    r46149 r46161  
    6060
    6161
     62
     63/** @interface_method_impl{RTDBGMODVTIMG,pfnGetFormat} */
     64static DECLCALLBACK(RTLDRFMT) rtDbgModLdr_GetFormat(PRTDBGMODINT pMod)
     65{
     66    PRTDBGMODLDR pThis = (PRTDBGMODLDR)pMod->pvImgPriv;
     67    return RTLdrGetFormat(pThis->hLdrMod);
     68}
     69
     70
    6271/** @interface_method_impl{RTDBGMODVTIMG,pfnUnmapPart} */
    6372static DECLCALLBACK(int) rtDbgModLdr_UnmapPart(PRTDBGMODINT pMod, size_t cb, void const **ppvMap)
     
    158167
    159168/** @interface_method_impl{RTDBGMODVTIMG,pfnTryOpen} */
    160 static DECLCALLBACK(int) rtDbgModLdr_TryOpen(PRTDBGMODINT pMod)
     169static DECLCALLBACK(int) rtDbgModLdr_TryOpen(PRTDBGMODINT pMod, RTLDRARCH enmArch)
    161170{
    162171    RTLDRMOD hLdrMod;
    163     int rc = RTLdrOpen(pMod->pszImgFile, RTLDR_O_FOR_DEBUG, RTLDRARCH_WHATEVER, &hLdrMod);
     172    int rc = RTLdrOpen(pMod->pszImgFile, RTLDR_O_FOR_DEBUG, enmArch, &hLdrMod);
    164173    if (RT_SUCCESS(rc))
    165174    {
     
    188197    /*.pfnMapPart = */                  rtDbgModLdr_MapPart,
    189198    /*.pfnUnmapPart = */                rtDbgModLdr_UnmapPart,
     199    /*.pfnGetFormat = */                rtDbgModLdr_GetFormat,
    190200
    191201    /*.u32EndMagic = */                 RTDBGMODVTIMG_MAGIC
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette