Changeset 41059 in vbox for trunk/src/VBox/Runtime
- Timestamp:
- Apr 26, 2012 12:52:15 AM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/testcase/tstLdr-3.cpp
r38636 r41059 39 39 40 40 41 static bool MyDisBlock(PDISCPUSTATE pCpu, RTHCUINTPTR pvCodeBlock, int32_t cbMax, RTUINTPTR off, RTUINTPTR Addr) 42 { 43 int32_t i = 0; 44 while (i < cbMax) 45 { 46 char szOutput[256]; 47 uint32_t cbInstr; 48 if (RT_FAILURE(DISInstr(pCpu, pvCodeBlock + i, off, &cbInstr, szOutput))) 49 return false; 50 51 RTPrintf("%s", szOutput); 52 if (pvCodeBlock + i + off == Addr) 53 RTPrintf("^^^^^^^^\n"); 54 55 /* next */ 56 i += cbInstr; 57 } 58 return true; 59 } 60 61 62 63 /** 64 * Resolve an external symbol during RTLdrGetBits(). 65 * 66 * @returns iprt status code. 67 * @param hLdrMod The loader module handle. 68 * @param pszModule Module name. 69 * @param pszSymbol Symbol name, NULL if uSymbol should be used. 70 * @param uSymbol Symbol ordinal, ~0 if pszSymbol should be used. 71 * @param pValue Where to store the symbol value (address). 72 * @param pvUser User argument. 73 */ 74 static DECLCALLBACK(int) testGetImport(RTLDRMOD hLdrMod, const char *pszModule, const char *pszSymbol, unsigned uSymbol, RTUINTPTR *pValue, void *pvUser) 75 { 76 RTUINTPTR BaseAddr = *(PCRTUINTPTR)pvUser; 77 *pValue = BaseAddr + UINT32_C(0x604020f0); 78 return VINF_SUCCESS; 79 } 80 81 82 /** 83 * Enumeration callback function used by RTLdrEnumSymbols(). 84 * 85 * @returns iprt status code. Failure will stop the enumeration. 86 * @param hLdrMod The loader module handle. 87 * @param pszSymbol Symbol name. NULL if ordinal only. 88 * @param uSymbol Symbol ordinal, ~0 if not used. 89 * @param Value Symbol value. 90 * @param pvUser The user argument specified to RTLdrEnumSymbols(). 91 */ 92 static DECLCALLBACK(int) testEnumSymbol1(RTLDRMOD hLdrMod, const char *pszSymbol, unsigned uSymbol, RTUINTPTR Value, void *pvUser) 93 { 94 RTPrintf(" %RTptr %s (%d)\n", Value, pszSymbol, uSymbol); 95 return VINF_SUCCESS; 96 } 41 /******************************************************************************* 42 * Global Variables * 43 *******************************************************************************/ 44 static RTUINTPTR g_uLoadAddr; 45 static RTLDRMOD g_hLdrMod; 46 static void *g_pvBits; 97 47 98 48 /** … … 163 113 } 164 114 115 static int FindNearSymbol(RTUINTPTR uAddr, PTESTNEARSYM pNearSym) 116 { 117 RT_ZERO(*pNearSym); 118 pNearSym->Addr = (RTUINTPTR)uAddr; 119 pNearSym->aSyms[1].Value = ~(RTUINTPTR)0; 120 int rc = RTLdrEnumSymbols(g_hLdrMod, RTLDR_ENUM_SYMBOL_FLAGS_ALL, g_pvBits, g_uLoadAddr, testEnumSymbol2, pNearSym); 121 if (RT_FAILURE(rc)) 122 RTPrintf("tstLdr-3: Failed to enumerate symbols: %Rra\n", rc); 123 return rc; 124 } 125 126 static DECLCALLBACK(int) MyGetSymbol(PCDISCPUSTATE pCpu, uint32_t u32Sel, RTUINTPTR uAddress, 127 char *pszBuf, size_t cchBuf, RTINTPTR *poff, 128 void *pvUser) 129 { 130 if ( uAddress > RTLdrSize(g_hLdrMod) + g_uLoadAddr 131 || uAddress < g_uLoadAddr) 132 return VERR_SYMBOL_NOT_FOUND; 133 134 TESTNEARSYM NearSym; 135 int rc = FindNearSymbol(uAddress, &NearSym); 136 if (RT_FAILURE(rc)) 137 return rc; 138 139 RTStrCopy(pszBuf, cchBuf, NearSym.aSyms[0].szName); 140 *poff = uAddress - NearSym.aSyms[0].Value; 141 return VINF_SUCCESS; 142 } 143 144 145 static DECLCALLBACK(int) MyReadBytes(RTUINTPTR uSrc, uint8_t *pbDst, unsigned cb, void *pvUser) 146 { 147 PDISCPUSTATE pCpu = (PDISCPUSTATE)pvUser; 148 memcpy(pbDst, (uint8_t const *)((uintptr_t)uSrc + (uintptr_t)pCpu->apvUserData[0]), cb); 149 return VINF_SUCCESS; 150 } 151 152 153 static bool MyDisBlock(PDISCPUSTATE pCpu, RTHCUINTPTR pvCodeBlock, int32_t cbMax, RTUINTPTR off, 154 RTUINTPTR uNearAddr, RTUINTPTR uSearchAddr) 155 { 156 int32_t i = 0; 157 while (i < cbMax) 158 { 159 bool fQuiet = RTAssertSetQuiet(true); 160 bool fMayPanic = RTAssertSetMayPanic(false); 161 char szOutput[256]; 162 unsigned cbInstr; 163 int rc = DISCoreOneEx(uNearAddr + i, pCpu->mode, 164 MyReadBytes, (uint8_t *)pvCodeBlock - (uintptr_t)uNearAddr, 165 pCpu, &cbInstr); 166 RTAssertSetMayPanic(fMayPanic); 167 RTAssertSetQuiet(fQuiet); 168 if (RT_FAILURE(rc)) 169 return false; 170 171 DISFormatYasmEx(pCpu, szOutput, sizeof(szOutput), 172 DIS_FMT_FLAGS_RELATIVE_BRANCH | DIS_FMT_FLAGS_BYTES_RIGHT | DIS_FMT_FLAGS_ADDR_LEFT | DIS_FMT_FLAGS_BYTES_SPACED, 173 MyGetSymbol, NULL); 174 175 RTPrintf("%s\n", szOutput); 176 if (pvCodeBlock + i + off == uSearchAddr) 177 RTPrintf("^^^^^^^^\n"); 178 179 /* next */ 180 i += cbInstr; 181 } 182 return true; 183 } 184 185 186 187 /** 188 * Resolve an external symbol during RTLdrGetBits(). 189 * 190 * @returns iprt status code. 191 * @param hLdrMod The loader module handle. 192 * @param pszModule Module name. 193 * @param pszSymbol Symbol name, NULL if uSymbol should be used. 194 * @param uSymbol Symbol ordinal, ~0 if pszSymbol should be used. 195 * @param pValue Where to store the symbol value (address). 196 * @param pvUser User argument. 197 */ 198 static DECLCALLBACK(int) testGetImport(RTLDRMOD hLdrMod, const char *pszModule, const char *pszSymbol, unsigned uSymbol, RTUINTPTR *pValue, void *pvUser) 199 { 200 #if 1 201 RTUINTPTR BaseAddr = *(PCRTUINTPTR)pvUser; 202 *pValue = BaseAddr + UINT32_C(0x604020f0); 203 #else 204 *pValue = UINT64_C(0xffffff7f820df000); 205 #endif 206 return VINF_SUCCESS; 207 } 208 209 210 /** 211 * Enumeration callback function used by RTLdrEnumSymbols(). 212 * 213 * @returns iprt status code. Failure will stop the enumeration. 214 * @param hLdrMod The loader module handle. 215 * @param pszSymbol Symbol name. NULL if ordinal only. 216 * @param uSymbol Symbol ordinal, ~0 if not used. 217 * @param Value Symbol value. 218 * @param pvUser The user argument specified to RTLdrEnumSymbols(). 219 */ 220 static DECLCALLBACK(int) testEnumSymbol1(RTLDRMOD hLdrMod, const char *pszSymbol, unsigned uSymbol, RTUINTPTR Value, void *pvUser) 221 { 222 RTPrintf(" %RTptr %s (%d)\n", Value, pszSymbol, uSymbol); 223 return VINF_SUCCESS; 224 } 225 226 227 static int testDisasNear(uint64_t uAddr) 228 { 229 TESTNEARSYM NearSym; 230 int rc = FindNearSymbol(uAddr, &NearSym); 231 if (RT_FAILURE(rc)) 232 return rc; 233 234 RTPrintf("tstLdr-3: Addr=%RTptr\n" 235 "%RTptr %s (%d) - %RTptr %s (%d)\n", 236 NearSym.Addr, 237 NearSym.aSyms[0].Value, NearSym.aSyms[0].szName, NearSym.aSyms[0].uSymbol, 238 NearSym.aSyms[1].Value, NearSym.aSyms[1].szName, NearSym.aSyms[1].uSymbol); 239 if (NearSym.Addr - NearSym.aSyms[0].Value < 0x10000) 240 { 241 DISCPUSTATE Cpu; 242 memset(&Cpu, 0, sizeof(Cpu)); 243 #ifdef RT_ARCH_X86 /** @todo select according to the module type. */ 244 Cpu.mode = CPUMODE_32BIT; 245 #else 246 Cpu.mode = CPUMODE_64BIT; 247 #endif 248 uint8_t *pbCode = (uint8_t *)g_pvBits + (NearSym.aSyms[0].Value - g_uLoadAddr); 249 MyDisBlock(&Cpu, (uintptr_t)pbCode, 250 RT_MAX(NearSym.aSyms[1].Value - NearSym.aSyms[0].Value, 0x20000), 251 NearSym.aSyms[0].Value - (RTUINTPTR)pbCode, 252 NearSym.aSyms[0].Value, 253 NearSym.Addr); 254 } 255 256 return VINF_SUCCESS; 257 } 165 258 166 259 int main(int argc, char **argv) … … 178 271 * Load the module. 179 272 */ 180 RTUINTPTR LoadAddr = (RTUINTPTR)RTStrToUInt64(argv[1]); 181 RTLDRMOD hLdrMod; 182 int rc = RTLdrOpen(argv[2], 0, RTLDRARCH_WHATEVER, &hLdrMod); 273 g_uLoadAddr = (RTUINTPTR)RTStrToUInt64(argv[1]); 274 int rc = RTLdrOpen(argv[2], 0, RTLDRARCH_WHATEVER, &g_hLdrMod); 183 275 if (RT_FAILURE(rc)) 184 276 { … … 187 279 } 188 280 189 void *pvBits = RTMemAlloc(RTLdrSize(hLdrMod));190 rc = RTLdrGetBits( hLdrMod, pvBits, LoadAddr, testGetImport, &LoadAddr);281 g_pvBits = RTMemAlloc(RTLdrSize(g_hLdrMod)); 282 rc = RTLdrGetBits(g_hLdrMod, g_pvBits, g_uLoadAddr, testGetImport, &g_uLoadAddr); 191 283 if (RT_SUCCESS(rc)) 192 284 { 193 if (argc > 3) 285 if ( argc == 4 286 && argv[3][0] == '*') 194 287 { 288 /* 289 * Wildcard address mode. 290 */ 291 uint64_t uWild = RTStrToUInt64(&argv[3][1]); 292 uint64_t uIncrements = strchr(argv[3], '/') ? RTStrToUInt64(strchr(argv[3], '/') + 1) : 0x1000; 293 if (!uIncrements) 294 uIncrements = 0x1000; 295 uint64_t uMax = RTLdrSize(g_hLdrMod) + g_uLoadAddr; 296 for (uint64_t uCur = g_uLoadAddr + uWild; uCur < uMax; uCur += uIncrements) 297 testDisasNear(uCur); 298 } 299 else if (argc > 3) 300 { 301 /* 302 * User specified addresses within the module. 303 */ 195 304 for (int i = 3; i < argc; i++) 196 305 { 197 TESTNEARSYM NearSym; 198 RT_ZERO(NearSym); 199 NearSym.Addr = (RTUINTPTR)RTStrToUInt64(argv[i]); 200 NearSym.aSyms[1].Value = ~(RTUINTPTR)0; 201 rc = RTLdrEnumSymbols(hLdrMod, RTLDR_ENUM_SYMBOL_FLAGS_ALL, pvBits, LoadAddr, testEnumSymbol2, &NearSym); 202 if (RT_SUCCESS(rc)) 203 { 204 RTPrintf("tstLdr-3: Addr=%RTptr\n" 205 "%RTptr %s (%d) - %RTptr %s (%d)\n", 206 NearSym.Addr, 207 NearSym.aSyms[0].Value, NearSym.aSyms[0].szName, NearSym.aSyms[0].uSymbol, 208 NearSym.aSyms[1].Value, NearSym.aSyms[1].szName, NearSym.aSyms[1].uSymbol); 209 if (NearSym.Addr - NearSym.aSyms[0].Value < 0x10000) 210 { 211 DISCPUSTATE Cpu; 212 memset(&Cpu, 0, sizeof(Cpu)); 213 #ifdef RT_ARCH_X86 /** @todo select according to the module type. */ 214 Cpu.mode = CPUMODE_32BIT; 215 #else 216 Cpu.mode = CPUMODE_64BIT; 217 #endif 218 uint8_t *pbCode = (uint8_t *)pvBits + (NearSym.aSyms[0].Value - LoadAddr); 219 MyDisBlock(&Cpu, (uintptr_t)pbCode, 220 RT_MAX(NearSym.aSyms[1].Value - NearSym.aSyms[0].Value, 0x20000), 221 NearSym.aSyms[0].Value - (RTUINTPTR)pbCode, 222 NearSym.Addr); 223 } 224 } 225 else 226 { 227 RTPrintf("tstLdr-3: Failed to enumerate symbols: %Rra\n", rc); 306 rc = testDisasNear(RTStrToUInt64(argv[i])); 307 if (RT_FAILURE(rc)) 228 308 rcRet++; 229 }230 309 } 231 310 } … … 235 314 * Enumerate symbols. 236 315 */ 237 rc = RTLdrEnumSymbols( hLdrMod, RTLDR_ENUM_SYMBOL_FLAGS_ALL, pvBits,LoadAddr, testEnumSymbol1, NULL);316 rc = RTLdrEnumSymbols(g_hLdrMod, RTLDR_ENUM_SYMBOL_FLAGS_ALL, g_pvBits, g_uLoadAddr, testEnumSymbol1, NULL); 238 317 if (RT_FAILURE(rc)) 239 318 { … … 245 324 else 246 325 { 247 RTPrintf("tstLdr-3: Failed to get bits for '%s' at %RTptr: %Rra\n", argv[2], LoadAddr, rc);326 RTPrintf("tstLdr-3: Failed to get bits for '%s' at %RTptr: %Rra\n", argv[2], g_uLoadAddr, rc); 248 327 rcRet++; 249 328 } 250 RTMemFree( pvBits);251 RTLdrClose( hLdrMod);329 RTMemFree(g_pvBits); 330 RTLdrClose(g_hLdrMod); 252 331 253 332 /*
Note:
See TracChangeset
for help on using the changeset viewer.