Changeset 45405 in vbox for trunk/src/VBox/Runtime/r0drv/nt/ntBldSymDb.cpp
- Timestamp:
- Apr 8, 2013 1:38:35 PM (12 years ago)
- svn:sync-xref-src-repo-rev:
- 84833
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r0drv/nt/ntBldSymDb.cpp
r45383 r45405 83 83 } MYSTRUCT; 84 84 85 /** Architecture. */ 86 typedef enum MYARCH 87 { 88 MYARCH_X86, 89 MYARCH_AMD64, 90 MYARCH_DETECT 91 } MYARCH; 92 85 93 /** Set of structures for one kernel. */ 86 94 typedef struct MYSET … … 92 100 /** The OS version we've harvested structs for */ 93 101 RTNTSDBOSVER OsVerInfo; 102 /** The architecture. */ 103 MYARCH enmArch; 94 104 /** The structures and their member. */ 95 105 MYSTRUCT aStructs[1]; … … 268 278 RTListForEach(&g_SetList, pSet, MYSET, ListEntry) 269 279 { 280 const char *pszArch = pSet->enmArch == MYARCH_AMD64 ? "AMD64" : "X86"; 270 281 RTStrmPrintf(pOut, 282 "#ifdef RT_ARCH_%s\n" 271 283 " { /* Source: %s */\n" 272 284 " /*.OsVerInfo = */\n" … … 279 291 " /* .uBuildNo = */ %u,\n" 280 292 " },\n", 293 pszArch, 281 294 pSet->pszPdb, 282 295 pSet->OsVerInfo.uMajorVer, … … 306 319 } 307 320 RTStrmPrintf(pOut, 308 " },\n"); 321 " },\n" 322 "#endif\n" 323 ); 309 324 } 310 325 … … 325 340 * @param pOsVerInfo The OS version info. 326 341 */ 327 static RTEXITCODE saveStructures(PRTNTSDBOSVER pOsVerInfo, const char *pszPdb)342 static RTEXITCODE saveStructures(PRTNTSDBOSVER pOsVerInfo, MYARCH enmArch, const char *pszPdb) 328 343 { 329 344 /* … … 346 361 * Copy over the data. 347 362 */ 363 pSet->enmArch = enmArch; 348 364 memcpy(&pSet->OsVerInfo, pOsVerInfo, sizeof(pSet->OsVerInfo)); 349 365 memcpy(&pSet->aStructs[0], g_aStructs, sizeof(g_aStructs)); … … 666 682 667 683 668 #if 0669 /** @name Path properties returned by RTPathParse and RTPathSplit.670 * @{ */671 /** Indicates that there is a filename.672 * If not set, a directory was specified using a trailing slash or a volume673 * was specified without any file/dir name following it. */674 #define RTPATH_PROP_FILENAME UINT16_C(0x0001)675 /** The filename has a suffix (extension). */676 #define RTPATH_PROP_SUFFIX UINT16_C(0x0002)677 /** Indicates that this is an UNC path (Windows and OS/2 only). */678 #define RTPATH_PROP_UNC UINT16_C(0x0010)679 /** A root is specified. The path is relative if not set. */680 #define RTPATH_PROP_ROOT UINT16_C(0x0020)681 /** A volume (drive) is specified. */682 #define RTPATH_PROP_VOLSPEC UINT16_C(0x0040)683 /** The path is absolute. */684 #define RTPATH_PROP_ABSOLUTE UINT16_C(0x0100)685 /** @} */686 687 688 /**689 * Parsed path.690 *691 * The first component is the root and volume specifier. If UNC, the first692 * component does not include the share/service name, that is found as the693 * second component if present.694 */695 typedef struct RTPATHPARSED696 {697 /** Number of path components. */698 uint16_t cComponents;699 /** The offset of the filename suffix, offset of the NUL char if none. */700 uint16_t offSuffix;701 /** Path property flags, RTPATH_PROP_XXX */702 uint16_t fProps;703 /** The number of bytes used (on success) or needed (on buffer overflow). */704 uint16_t cbUsed;705 /** Array of component descriptors (variable size). */706 struct707 {708 /** The offset of the component. */709 uint16_t off;710 /** The */711 uint16_t cch;712 } aComponents[1];713 } RTPATHPARSED;714 /** Pointer to to a parsed path result. */715 typedef RTPATHPARSED *PRTPATHPARSED;716 /** Pointer to to a const parsed path result. */717 typedef RTPATHPARSED *PCRTPATHPARSED;718 719 720 int RTPathParse(const char *pszPath, PRTPATHPARSED pOutput, size_t cbOutput)721 {722 AssertReturn(cbOutput >= sizeof(*pOutput), VERR_INVALID_PARAMETER);723 AssertPtrReturn(pszPath, VERR_INVALID_POINTER);724 AssertPtrReturn(pOutput, VERR_INVALID_POINTER);725 726 }727 728 729 730 731 typedef struct RTPATHSPLIT732 {733 /** Number of path components. */734 uint32_t cComponents;735 /** The first directory. */736 uint8_t iFirstDir;737 uint8_t fReserved1; /**< Reserved */738 /** Path property flags, RTPATHSPLIT_PROP_XXX */739 uint16_t fProps;740 /** Pointer to the dot in the filename suffix. If no suffix, this points to741 * the terminator character. */742 const char *pszSuffix;743 /** Array of pointers to components.744 * @remarks This is variable sized and is followed by the strings it points to.745 * It's set to 8 instead of the usual 1 as that's the minimum size of746 * the RTPathSplit buffer. */747 const char *apszComponents[8];748 } RTPATHSPLIT;749 /** Pointer to to a path split result. */750 typedef RTPATHSPLIT *PRTPATHSPLIT;751 /** Pointer to to a const path split result. */752 typedef RTPATHSPLIT *PCRTPATHSPLIT;753 754 755 int RTPathSplit(const char *pszPath, PRTPATHSPLIT pOutput, size_t cbOutput)756 {757 AssertReturn(cbOutput >= sizeof(*pOutput), VERR_BUFFER_UNDERFLOW);758 AssertPtr(pszPath);759 AsserPtr(pOutput);760 761 /*762 * Parse the path, we're using apszComponents to store offset + length of763 * each component while parsing to avoid duplicating code and effort.764 */765 struct TMPOFFSIZE766 {767 uint16_t off;768 uint16_t cch;769 } *paComponents = (struct TMPOFFSIZE *)&pOutput->apszComponents;770 uint32_t cMaxComponents = (cbOutput - RT_OFFSETOF(RTPATHSPLIT, apszComponents)) / sizeof(paComponents[0]);771 uint32_t iComponent = 0;772 size_t cbStrings = 0;773 uint16_t fFlags = 0;774 size_t off = 0;775 776 paComponents[0].off = 0;777 778 /* The volume specifier bit first, it's special. */779 if (RTPATH_IS_SLASH(pszPath[0]))780 {781 #if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS)782 if ( RTPATH_IS_SLASH(pszPath[1])783 && !RTPATH_IS_SLASH(pszPath[2])784 && pszPath[2])785 {786 fFlags |= RTPATHSPLIT_PROP_UNC;787 788 /* UNC server name */789 off = 2;790 while (!RTPATH_IS_SLASH(pszPath[off]) && pszPath[off])791 off++;792 paComponents[0].cch = off;793 size_t cbStrings = 0;794 795 796 while (RTPATH_IS_SLASH(pszPath[off]))797 off++;798 799 /* UNC share */800 while (!RTPATH_IS_SLASH(pszPath[off]) && pszPath[off])801 off++;802 }803 else804 #endif805 {806 fFlags |= RTPATHSPLIT_PROP_ROOT;807 cbString = sizeof("/");808 iComponent = 1;809 off = 1;810 }811 while (RTPATH_IS_SLASH(pszPath[off]))812 off++;813 }814 #if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS)815 else if (RT_C_IS_ALPHA(pszPath[0]) && pszPath[1] == ':')816 {817 off = 2;818 while (RTPATH_IS_SLASH(pszPath[off]))819 off++;820 }821 #endif822 Assert(!RTPATH_IS_SLASH(pszPath[off]));823 824 825 }826 827 #endif828 829 684 /** 830 685 * Use various hysterics to figure out the OS version details from the PDB path. … … 839 694 * @param pszPdb The path to the PDB. 840 695 * @param pVerInfo Where to return the version info. 841 */ 842 static RTEXITCODE FigurePdbVersionInfo(const char *pszPdb, PRTNTSDBOSVER pVerInfo) 843 { 844 const char *pszFilename = RTPathFilename(pszPdb); 845 696 * @param penmArch Where to return the architecture. 697 */ 698 static RTEXITCODE FigurePdbVersionInfo(const char *pszPdb, PRTNTSDBOSVER pVerInfo, MYARCH *penmArch) 699 { 700 /* 701 * Split the path. 702 */ 703 union 704 { 705 RTPATHSPLIT Split; 706 uint8_t abPad[RTPATH_MAX + 1024]; 707 } u; 708 int rc = RTPathSplit(pszPdb, &u.Split, sizeof(u), 0); 709 if (RT_FAILURE(rc)) 710 return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPathSplit failed on '%s': %Rrc", pszPdb, rc); 711 if (!(u.Split.fProps & RTPATH_PROP_FILENAME)) 712 return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPATH_PROP_FILENAME not set for: '%s'", pszPdb); 713 const char *pszFilename = u.Split.apszComps[u.Split.cComps - 1]; 714 715 /* 716 * SMP or UNI kernel? 717 */ 846 718 if (!RTStrICmp(pszFilename, "ntkrnlmp.pdb")) 847 719 pVerInfo->fSmp = true; … … 851 723 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Doesn't recognize the filename '%s'...", pszFilename); 852 724 853 /* testing only */ 725 /* 726 * Look for symbol pack names in the path. This is stuff like: 727 * - WindowsVista.6002.090410-1830.x86fre 728 * - WindowsVista.6002.090410-1830.amd64chk 729 * - Windows_Win7.7600.16385.090713-1255.X64CHK 730 * - Windows_Win7SP1.7601.17514.101119-1850.AMD64FRE 731 * - Windows_Win8.9200.16384.120725-1247.X86CHK 732 */ 733 bool fFound = false; 734 uint32_t i = u.Split.cComps - 1; 735 while (i-- > 0) 736 { 737 static struct 738 { 739 const char *pszPrefix; 740 size_t cchPrefix; 741 uint8_t uMajorVer; 742 uint8_t uMinorVer; 743 uint8_t uCsdNo; 744 uint8_t uChecked; /**< */ 745 MYARCH enmArch; 746 uint32_t uBuildNo; /**< UINT32_MAX means the number immediately after the prefix. */ 747 } const s_aSymPacks[] = 748 { 749 { RT_STR_TUPLE("Windows2003."), 5, 2, 0, UINT8_MAX, MYARCH_DETECT, UINT32_MAX }, 750 { RT_STR_TUPLE("WindowsVista.6000."), 6, 0, 0, UINT8_MAX, MYARCH_DETECT, 6000 }, 751 { RT_STR_TUPLE("Windows_Longhorn.6001."), 6, 0, 1, UINT8_MAX, MYARCH_DETECT, 6001 }, /* server 2008 */ 752 { RT_STR_TUPLE("WindowsVista.6002."), 6, 0, 2, UINT8_MAX, MYARCH_DETECT, 6002 }, 753 }; 754 755 const char *pszComp = u.Split.apszComps[i]; 756 uint32_t j = RT_ELEMENTS(s_aSymPacks); 757 while (j-- > 0) 758 if (!RTStrNICmp(pszComp, s_aSymPacks[i].pszPrefix, s_aSymPacks[i].cchPrefix)) 759 break; 760 if (j >= RT_ELEMENTS(s_aSymPacks)) 761 continue; 762 763 pVerInfo->uMajorVer = s_aSymPacks[j].uMajorVer; 764 pVerInfo->uMinorVer = s_aSymPacks[j].uMinorVer; 765 pVerInfo->uCsdNo = s_aSymPacks[j].uCsdNo; 766 pVerInfo->fChecked = s_aSymPacks[j].uChecked == 1; 767 pVerInfo->uBuildNo = s_aSymPacks[j].uBuildNo; 768 *penmArch = s_aSymPacks[j].enmArch; 769 770 /* Parse build number if necessary. */ 771 if (s_aSymPacks[j].uBuildNo == UINT32_MAX) 772 { 773 char *pszNext; 774 rc = RTStrToUInt32Ex(pszComp + s_aSymPacks[j].cchPrefix, &pszNext, 10, &pVerInfo->uBuildNo); 775 if (RT_FAILURE(rc)) 776 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to decode build number in '%s': %Rrc", pszComp, rc); 777 if (*pszNext != '.' && *pszNext != '_' && *pszNext != '-') 778 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to decode build number in '%s': '%c'", pszComp, *pszNext); 779 } 780 781 /* Look for build arch and checked/free. */ 782 if ( RTStrIStr(pszComp, ".x86.chk.") 783 || RTStrIStr(pszComp, ".x86chk.") 784 || RTStrIStr(pszComp, "_x86_chk_") 785 || RTStrIStr(pszComp, "_x86chk_") 786 || RTStrIStr(pszComp, "-x86-DEBUG") 787 || (RTStrIStr(pszComp, "-x86-") && RTStrIStr(pszComp, "-DEBUG")) 788 ) 789 { 790 pVerInfo->fChecked = true; 791 *penmArch = MYARCH_X86; 792 } 793 else if ( RTStrIStr(pszComp, ".amd64.chk.") 794 || RTStrIStr(pszComp, ".amd64chk.") 795 || RTStrIStr(pszComp, ".x64.chk.") 796 || RTStrIStr(pszComp, ".x64chk.") 797 ) 798 { 799 pVerInfo->fChecked = true; 800 *penmArch = MYARCH_AMD64; 801 } 802 else if ( RTStrIStr(pszComp, ".amd64.fre.") 803 || RTStrIStr(pszComp, ".amd64fre.") 804 || RTStrIStr(pszComp, ".x64.fre.") 805 || RTStrIStr(pszComp, ".x64fre.") 806 ) 807 { 808 pVerInfo->fChecked = false; 809 *penmArch = MYARCH_AMD64; 810 } 811 else if (RTStrIStr(pszComp, "DEBUG")) 812 { 813 pVerInfo->fChecked = true; 814 *penmArch = MYARCH_X86; 815 } 816 else 817 { 818 pVerInfo->fChecked = false; 819 *penmArch = MYARCH_X86; 820 } 821 return RTEXITCODE_SUCCESS; 822 } 823 824 825 /* 826 * testing only 827 */ 854 828 if (strIEndsWith(pszPdb, "ntkrnlmp.pdb\\B2DA40502FA744C18B9022FD187ADB592\\ntkrnlmp.pdb")) 855 829 { … … 888 862 * Figure the windows version details for the given PDB. 889 863 */ 864 MYARCH enmArch; 890 865 RTNTSDBOSVER OsVerInfo; 891 RTEXITCODE rcExit = FigurePdbVersionInfo(pszPdb, &OsVerInfo );866 RTEXITCODE rcExit = FigurePdbVersionInfo(pszPdb, &OsVerInfo, &enmArch); 892 867 if (rcExit != RTEXITCODE_SUCCESS) 893 868 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to figure the OS version info for '%s'.\n'", pszPdb); … … 922 897 * Save the details for later when we produce the header. 923 898 */ 924 rcExit = saveStructures(&OsVerInfo, pszPdb);899 rcExit = saveStructures(&OsVerInfo, enmArch, pszPdb); 925 900 } 926 901 } … … 1087 1062 RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 1088 1063 RTGETOPTINIT_FLAGS_OPTS_FIRST); 1089 while ((ch = RTGetOpt(&GetState, &ValueUnion)) )1064 while ((ch = RTGetOpt(&GetState, &ValueUnion)) != 0) 1090 1065 { 1091 1066 switch (ch)
Note:
See TracChangeset
for help on using the changeset viewer.