Changeset 3541
- Timestamp:
- Aug 25, 2007, 5:46:14 AM (18 years ago)
- Location:
- trunk/kStuff
- Files:
-
- 2 added
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kStuff/include/k/kDbg.h
r3540 r3541 41 41 /** The max symbol name length used by the debug reader. */ 42 42 #define KDBG_SYMBOL_MAX 384 43 44 /** @name kDbg Status codes45 * (Success is indicated by the value 0.)46 * @{ */47 #define KDBG_ERR_BASE 43000048 49 /** An API was given an invalid parameter. */50 #define KDBG_ERR_INVALID_PARAMETER (KDBG_ERR_BASE + 0)51 /** A pointer argument is not valid. */52 #define KDBG_ERR_INVALID_POINTER (KDBG_ERR_BASE + 1)53 /** A handle argument is not valid. */54 #define KDBG_ERR_INVALID_HANDLE (KDBG_ERR_BASE + 2)55 /** A parameter is out of range. */56 #define KDBG_ERR_OUT_OF_RANGE (KDBG_ERR_BASE + 3)57 /** Out of memory. */58 #define KDBG_ERR_NO_MEMORY (KDBG_ERR_BASE + 4)59 /** The specified file was not found. */60 #define KDBG_ERR_FILE_NOT_FOUND (KDBG_ERR_BASE + 5)61 /** Hit some unimplemented functionality - feel free to implement it :-) . */62 #define KDBG_ERR_NOT_IMPLEMENTED (KDBG_ERR_BASE + 6)63 /** Generic error. */64 #define KDBG_ERR_GENERAL_FAILURE (KDBG_ERR_BASE + 9)65 66 /** The (module) format isn't known to use. */67 #define KDBG_ERR_UNKOWN_FORMAT (KDBG_ERR_BASE + 10)68 /** The (module) format isn't supported by this kDbg build. */69 #define KDBG_ERR_FORMAT_NOT_SUPPORTED (KDBG_ERR_BASE + 11)70 /** A specified address or an address found in the debug info is invalid. */71 #define KDBG_ERR_INVALID_ADDRESS (KDBG_ERR_BASE + 12)72 /** The dbghelp.dll is too old or something like that. */73 #define KDBG_ERR_DBGHLP_VERSION_MISMATCH (KDBG_ERR_BASE + 13)74 /** Invalid executable format. */75 #define KDBG_ERR_BAD_EXE_FORMAT (KDBG_ERR_BASE + 14)76 77 /** @} */78 79 43 80 44 /** @name Special Segments … … 131 95 * 132 96 * @returns VINF_SUCCESS on success. 133 * @returns K DBG_ERR_INVALID_POINTER if a NULL pointer or an !KDBG_VALID_PTR() is passed in.97 * @returns KERR_INVALID_POINTER if a NULL pointer or an !KDBG_VALID_PTR() is passed in. 134 98 * 135 99 * @param pLine The line number to be freed. … … 199 163 * 200 164 * @returns VINF_SUCCESS on success. 201 * @returns K DBG_ERR_INVALID_POINTER if a NULL pointer or an !KDBG_VALID_PTR() is passed in.165 * @returns KERR_INVALID_POINTER if a NULL pointer or an !KDBG_VALID_PTR() is passed in. 202 166 * 203 167 * @param pSymbol The symbol to be freed. … … 206 170 207 171 172 /** Pointer to a kDbgHlp file structure (abstract). */ 173 typedef struct KDBGHLPFILE *PKDBGHLPFILE; 208 174 209 175 /** A debug module handle. */ 210 176 typedef struct KDBGMOD *PKDBGMOD; 177 178 /** 179 * The debug module method table. 180 */ 181 typedef struct KDBGMODOPS 182 { 183 /** The name of the reader. */ 184 const char *pszName; 185 186 /** Pointer to the next debug module readers. 187 * This is only used for dynamically registered readers. */ 188 struct KDBGMODOPS *pNext; 189 190 /** 191 * Tries to open the module. 192 * 193 * @returns 0 on success, KDBG_ERR on failure. 194 * @param pFile The file 195 * @param ppMod Where to store the module that's been opened. 196 * @param off The file offset of the debug info. This is 0 if there isn't 197 * any specfic debug info section and the reader should start 198 * looking for debug info at the start of the file. 199 * @param cb The size of the debug info in the file. INT64_MAX if we don't 200 * know or there isn't any particular debug info section in the file. 201 * @param pLdrMod The associated loader module. This can be NULL. 202 * 203 * @remark This is NULL for the builtin readers. 204 */ 205 int (*pfnOpen)(PKDBGMOD *ppMod, PKDBGHLPFILE pFile, KFOFF off, KFOFF cb, struct KLDRMOD *pLdrMod); 206 207 /** 208 * Closes the module. 209 * 210 * This should free all resources associated with the module 211 * except the pMod which is freed by the caller. 212 * 213 * @returns IPRT status code. 214 * @param pMod The module. 215 */ 216 int (*pfnClose)(PKDBGMOD pMod); 217 218 /** 219 * Gets a symbol by segment:offset. 220 * This will be approximated to the nearest symbol if there is no exact match. 221 * 222 * @returns 0 on success. KLDR_ERR_* on failure. 223 * @param pMod The module. 224 * @param iSegment The segment this offset is relative to. 225 * The -1 segment is special, it means that the addres is relative to 226 * the image base. The image base is where the first bit of the image 227 * is mapped during load. 228 * @param off The offset into the segment. 229 * @param pSym Where to store the symbol details. 230 */ 231 int (*pfnQuerySymbol)(PKDBGMOD pMod, KI32 iSegment, KDBGADDR off, PKDBGSYMBOL pSym); 232 233 /** 234 * Gets a line number entry by segment:offset. 235 * This will be approximated to the nearest line number there is no exact match. 236 * 237 * @returns 0 on success. KLDR_ERR_* on failure. 238 * @param pMod The module. 239 * @param iSegment The segment this offset is relative to. 240 * The -1 segment is special, it means that the addres is relative to 241 * the image base. The image base is where the first bit of the image 242 * is mapped during load. 243 * @param off The offset into the segment. 244 * @param pLine Where to store the line number details. 245 */ 246 int (*pfnQueryLine)(PKDBGMOD pMod, KI32 iSegment, KDBGADDR uOffset, PKDBGLINE pLine); 247 248 /** This is just to make sure you've initialized all the fields. 249 * Must be identical to pszName. */ 250 const char *pszName2; 251 } KDBGMODOPS; 252 /** Pointer to a module method table. */ 253 typedef KDBGMODOPS *PKDBGMODOPS; 254 /** Pointer to a const module method table. */ 255 typedef const KDBGMODOPS *PCKDBGMODOPS; 256 257 /** 258 * Register a debug module reader with the kDbgModule component. 259 * 260 * Dynamically registered readers are kept in FIFO order, and external 261 * readers will be tried after the builtin ones. 262 * 263 * @returns 0 on success. 264 * @returns KERR_INVALID_POINTER if pOps is missing bits. 265 * @returns KERR_INVALID_PARAMETER if pOps is already in the list. 266 * @param pOps The reader method table, kDbg takes owner ship of 267 * this. This must be writeable as the pNext pointer 268 * will be update. It must also stick around for as 269 * long as kDbg is in use. 270 */ 271 KDBG_DECL(int) kDbgModuleRegisterReader(PKDBGMODOPS pOps) 272 ; 273 274 275 276 /** 277 * Internal representation of a debug module. 278 */ 279 typedef struct KDBGMOD 280 { 281 /** Magic value (KDBGMOD_MAGIC). */ 282 KI32 u32Magic; 283 /** The handle to the module. (If closed, this is NIL_RTFILE.) */ 284 PKDBGHLPFILE pFile; 285 /** Pointer to the method table. */ 286 PCKDBGMODOPS pOps; 287 } KDBGMOD; 288 289 290 /** The magic value for the debug module structure. (Some dead english writer) */ 291 #define KDBGMOD_MAGIC 0x19200501 292 /** The magic value of a dead module structure. */ 293 #define KDBGMOD_MAGIC_DEAD 0x19991231 294 211 295 212 296 /** … … 240 324 * @param pSym Where to store the symbol details. 241 325 */ 242 KDBG_DECL(int) kDbgModuleQuerySymbol(PKDBGMOD pMod, int32_tiSegment, KDBGADDR off, PKDBGSYMBOL pSym);326 KDBG_DECL(int) kDbgModuleQuerySymbol(PKDBGMOD pMod, KI32 iSegment, KDBGADDR off, PKDBGSYMBOL pSym); 243 327 244 328 /** … … 256 340 * Free the returned symbol using kDbgSymbolFree(). 257 341 */ 258 KDBG_DECL(int) kDbgModuleQuerySymbolA(PKDBGMOD pMod, int32_tiSegment, KDBGADDR off, PPKDBGSYMBOL ppSym);342 KDBG_DECL(int) kDbgModuleQuerySymbolA(PKDBGMOD pMod, KI32 iSegment, KDBGADDR off, PPKDBGSYMBOL ppSym); 259 343 260 344 /** … … 271 355 * @param pLine Where to store the line number details. 272 356 */ 273 KDBG_DECL(int) kDbgModuleQueryLine(PKDBGMOD pMod, int32_tiSegment, KDBGADDR off, PKDBGLINE pLine);357 KDBG_DECL(int) kDbgModuleQueryLine(PKDBGMOD pMod, KI32 iSegment, KDBGADDR off, PKDBGLINE pLine); 274 358 275 359 /** … … 287 371 * Free the returned line number using kDbgLineFree(). 288 372 */ 289 KDBG_DECL(int) kDbgModuleQueryLineA(PKDBGMOD pMod, int32_tiSegment, KDBGADDR off, PPKDBGLINE ppLine);373 KDBG_DECL(int) kDbgModuleQueryLineA(PKDBGMOD pMod, KI32 iSegment, KDBGADDR off, PPKDBGLINE ppLine); 290 374 291 375 -
trunk/kStuff/include/k/kDefs.h
r3538 r3541 371 371 #define K_ALIGN_P(pv, align) ( (void *)( ((KUPTR)(pv) + ((align) - 1)) & ~(KUPTR)((align) - 1) ) ) 372 372 /** Number of elements in an array. */ 373 #define K_ELEMENTS(a) ( sizeof(a) / sizeof((a)[ 373 #define K_ELEMENTS(a) ( sizeof(a) / sizeof((a)[0]) ) 374 374 /** Checks if the specified pointer is a valid address or not. */ 375 375 #define K_VALID_PTR(ptr) ( (KUPTR)(ptr) + 0x1000U >= 0x2000U ) -
trunk/kStuff/include/k/kTypes.h
r3538 r3541 7 7 * 8 8 * 9 * This file is part of k *.10 * 11 * k *is free software; you can redistribute it and/or modify9 * This file is part of kStuff. 10 * 11 * kStuff is free software; you can redistribute it and/or modify 12 12 * it under the terms of the GNU Lesser General Public License as published 13 13 * by the Free Software Foundation; either version 2 of the License, or 14 14 * (at your option) any later version. 15 15 * 16 * k *is distributed in the hope that it will be useful,16 * kStuff is distributed in the hope that it will be useful, 17 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the … … 20 20 * 21 21 * You should have received a copy of the GNU Lesser General Public License 22 * along with k *; if not, write to the Free Software22 * along with kStuff; if not, write to the Free Software 23 23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 24 * … … 33 33 * @{ 34 34 */ 35 36 35 37 36 /** @typedef KI64 … … 45 44 * 64-bit unsigned integer constant. 46 45 * @param c The constant value. */ 46 /** @def KI64_PRI 47 * 64-bit signed integer printf format. */ 48 /** @def KU64_PRI 49 * 64-bit unsigned integer printf format. */ 50 /** @def KX64_PRI 51 * 64-bit signed and unsigned integer hexadecimal printf format. */ 47 52 48 53 /** @typedef KI32 … … 56 61 * 32-bit unsigned integer constant. 57 62 * @param c The constant value. */ 63 /** @def KI32_PRI 64 * 32-bit signed integer printf format. */ 65 /** @def KU32_PRI 66 * 32-bit unsigned integer printf format. */ 67 /** @def KX32_PRI 68 * 32-bit signed and unsigned integer hexadecimal printf format. */ 58 69 59 70 /** @typedef KI16 … … 67 78 * 16-bit unsigned integer constant. 68 79 * @param c The value. */ 80 /** @def KI16_PRI 81 * 16-bit signed integer printf format. */ 82 /** @def KU16_PRI 83 * 16-bit unsigned integer printf format. */ 84 /** @def KX16_PRI 85 * 16-bit signed and unsigned integer hexadecimal printf format. */ 69 86 70 87 /** @typedef KI8 … … 78 95 * 8-bit unsigned integer constant. 79 96 * @param c The constant value. */ 97 /** @def KI8_PRI 98 * 8-bit signed integer printf format. */ 99 /** @def KU8_PRI 100 * 8-bit unsigned integer printf format. */ 101 /** @def KX8_PRI 102 * 8-bit signed and unsigned integer hexadecimal printf format. */ 80 103 81 104 /** @typedef KSIZE … … 95 118 /** @def KSSIZE_MIN 96 119 * Memory size min constant.*/ 120 /** @def KSIZE_PRI 121 * Memory size printf format. */ 122 /** @def KSSIZE_PRI 123 * Memory size printf format. */ 97 124 98 125 /** @typedef KIPTR … … 112 139 /** @def KUPTR_MAX 113 140 * Unsigned pointer max constant.*/ 141 /** @def KIPTR_PRI 142 * Signed pointer printf format. */ 143 /** @def KUPTR_PRI 144 * Unsigned pointer printf format. */ 114 145 115 146 … … 119 150 typedef signed __int64 KI64; 120 151 typedef unsigned __int64 KU64; 152 #define KI64_PRI "I64d" 153 #define KU64_PRI "I64u" 154 #define KX64_PRI "I64x" 121 155 # else 122 156 typedef signed long long int KI64; 123 157 typedef unsigned long long int KU64; 158 #define KI64_PRI "lld" 159 #define KU64_PRI "llu" 160 #define KX64_PRI "llx" 124 161 # endif 125 162 typedef signed int KI32; … … 138 175 #define KU8_C(c) (c) 139 176 177 #define KI32_PRI "d" 178 #define KU32_PRI "u" 179 #define KX32_PRI "x" 180 #define KI16_PRI "d" 181 #define KU16_PRI "u" 182 #define KX16_PRI "x" 183 #define KI8_PRI "d" 184 #define KU8_PRI "u" 185 #define KX8_PRI "x" 186 140 187 typedef KI32 KSSIZE; 141 typedef KU32 KSIZE;142 typedef KI32 KIPTR;143 typedef KU32 KUPTR;144 188 #define KSSIZE(c) KI32_C(c) 145 189 #define KSSIZE_MAX KI32_MAX 146 190 #define KSSIZE_MIN KI32_MIN 191 #define KSSIZE_PRI KX32_PRI 192 193 typedef KU32 KSIZE; 147 194 #define KSIZE_C(c) KU32_C(c) 148 195 #define KSIZE_MAX KU32_MAX 196 #define KSIZE_PRI KX32_PRI 149 197 #define KIPTR_C(c) KI32_C(c) 198 199 typedef KI32 KIPTR; 150 200 #define KIPTR_MAX KI32_MAX 151 201 #define KIPTR_MIN KI32_MIN 202 #define KIPTR_PRI KX32_PRI 203 204 typedef KU32 KUPTR; 152 205 #define KUPTR_C(c) KU32_C(c) 153 206 #define KUPTR_MAX KU32_MAX 207 #define KUPTR_PRI KX32_PRI 154 208 155 209 … … 160 214 typedef signed __int64 KI64; 161 215 typedef unsigned __int64 KU64; 216 # define KI64_PRI "I64d" 217 # define KU64_PRI "I64u" 218 # define KX64_PRI "I64x" 162 219 # else 163 220 typedef signed long long int KI64; 164 221 typedef unsigned long long int KU64; 222 # define KI64_PRI "lld" 223 # define KU64_PRI "llu" 224 # define KX64_PRI "llx" 165 225 # endif 166 226 # define KI64_C(c) (c ## ULL) … … 169 229 typedef signed long int KI64; 170 230 typedef unsigned long int KU64; 171 # define KI64_C(c) (c ## UL) 172 # define KU64_C(c) (c ## L) 231 # define KI64_C(c) (c ## UL) 232 # define KU64_C(c) (c ## L) 233 # define KI64_PRI "ld" 234 # define KU64_PRI "lu" 235 # define KX64_PRI "lx" 173 236 # endif 174 237 typedef signed int KI32; … … 185 248 #define KU8_C(c) (c) 186 249 250 #define KI32_PRI "d" 251 #define KU32_PRI "u" 252 #define KX32_PRI "x" 253 #define KI16_PRI "d" 254 #define KU16_PRI "u" 255 #define KX16_PRI "x" 256 #define KI8_PRI "d" 257 #define KU8_PRI "u" 258 #define KX8_PRI "x" 259 187 260 typedef KI64 KSSIZE; 188 typedef KU64 KSIZE;189 typedef KI64 KIPTR;190 typedef KU64 KUPTR;191 261 #define KSSIZE(c) KI64_C(c) 192 262 #define KSSIZE_MAX KI64_MAX 193 263 #define KSSIZE_MIN KI64_MIN 264 #define KSSIZE_PRI KX64_PRI 265 266 typedef KU64 KSIZE; 194 267 #define KSIZE_C(c) KU64_C(c) 195 268 #define KSIZE_MAX KU64_MAX 269 #define KSIZE_PRI KX64_PRI 270 271 typedef KI64 KIPTR; 196 272 #define KIPTR_C(c) KI64_C(c) 197 273 #define KIPTR_MAX KI64_MAX 198 274 #define KIPTR_MIN KI64_MIN 275 #define KIPTR_PRI KX64_PRI 276 277 typedef KU64 KUPTR; 199 278 #define KUPTR_C(c) KU64_C(c) 200 279 #define KUPTR_MAX KU64_MAX 280 #define KUPTR_PRI KX64_PRI 201 281 202 282 #else … … 230 310 #define KU64_MAX KU64_C(0xffffffffffffffff) 231 311 312 /** File offset. */ 313 typedef KI64 KFOFF; 314 /** Pointer a file offset. */ 315 typedef KFOFF *PFOFF; 316 /** Pointer a const file offset. */ 317 typedef KFOFF *PCFOFF; 318 /** The min value for the KFOFF type. */ 319 #define KFOFF_MIN KI64_MIN 320 /** The max value for the KFOFF type. */ 321 #define KFOFF_MAX KI64_MAX 322 /** File offset contstant. 323 * @param c The constant value. */ 324 #define KFOFF_C(c) KI64_C(c) 325 /** File offset printf format. */ 326 #define KFOFF_PRI KI64_PRI 327 232 328 /** @} */ 233 329 -
trunk/kStuff/kDbg/kDbgHlp.h
r3540 r3541 97 97 * @{ 98 98 */ 99 /** Pointer to a kDbgHlp file structure (abstract). */100 typedef struct KDBGHLPFILE *PKDBGHLPFILE;101 102 99 /** 103 100 * Opens the specified file as read-only, buffered if possible. … … 285 282 #define kDbgAssertPtr(ptr) kDbgAssertMsg(KDBG_VALID_PTR(ptr), ("%s = %p\n", #ptr, (ptr))) 286 283 #define kDbgAssertPtrReturn(ptr, rcRet) kDbgAssertMsgReturn(KDBG_VALID_PTR(ptr), ("%s = %p -> %d\n", #ptr, (ptr), (rcRet)), (rcRet)) 284 #define kDbgAssertPtrNull(ptr) kDbgAssertMsg(!(ptr) || KDBG_VALID_PTR(ptr), ("%s = %p\n", #ptr, (ptr))) 285 #define kDbgAssertPtrNullReturn(ptr, rcRet) kDbgAssertMsgReturn(!(ptr) || KDBG_VALID_PTR(ptr), ("%s = %p -> %d\n", #ptr, (ptr), (rcRet)), (rcRet)) 287 286 #define kDbgAssertRC(rc) kDbgAssertMsg((rc) == 0, ("%s = %d\n", #rc, (rc))) 288 287 #define kDbgAssertRCReturn(rc, rcRet) kDbgAssertMsgReturn((rc) == 0, ("%s = %d -> %d\n", #rc, (rc), (rcRet)), (rcRet)) -
trunk/kStuff/kDbg/kDbgHlpCrt.cpp
r3537 r3541 93 93 { 94 94 case 0: return 0; 95 case EINVAL: return K DBG_ERR_INVALID_PARAMETER;96 case ENOMEM: return K DBG_ERR_NO_MEMORY;95 case EINVAL: return KERR_INVALID_PARAMETER; 96 case ENOMEM: return KERR_NO_MEMORY; 97 97 case EISDIR: 98 case ENOENT: return K DBG_ERR_FILE_NOT_FOUND;99 default: return K DBG_ERR_GENERAL_FAILURE;98 case ENOENT: return KERR_FILE_NOT_FOUND; 99 default: return KERR_GENERAL_FAILURE; 100 100 } 101 101 } … … 106 106 PKDBGHLPFILE pFile = (PKDBGHLPFILE)kDbgHlpAlloc(sizeof(*pFile)); 107 107 if (!pFile) 108 return K DBG_ERR_NO_MEMORY;108 return KERR_NO_MEMORY; 109 109 110 110 pFile->pStrm = fopen(pszFilename, "rb"); … … 181 181 long l = (long)off; 182 182 if (l != off) 183 return K DBG_ERR_OUT_OF_RANGE;183 return KERR_OUT_OF_RANGE; 184 184 if (!fseek(pFile->pStrm, l, SEEK_SET)) 185 185 return 0; … … 197 197 long l = (long)off; 198 198 if (l != off) 199 return K DBG_ERR_OUT_OF_RANGE;199 return KERR_OUT_OF_RANGE; 200 200 if (!fseek(pFile->pStrm, l, SEEK_CUR)) 201 201 return 0; … … 213 213 long l = (long)off; 214 214 if (l != off) 215 return K DBG_ERR_OUT_OF_RANGE;215 return KERR_OUT_OF_RANGE; 216 216 if (!fseek(pFile->pStrm, -l, SEEK_END)) 217 217 return 0; -
trunk/kStuff/kDbg/kDbgInternal.h
r3540 r3541 33 33 #endif 34 34 35 36 /** 37 * The debug module method table. 38 */ 39 typedef struct KDBGMODOPS 40 { 41 /** The name of the reader. */ 42 const char *pszName; 43 44 /** Pointer to the next debug module readers. 45 * This is only used for dynamically registered readers. */ 46 struct KDBGMODOPS *pNext; 47 48 /** 49 * Tries to open the module. 50 * 51 * @returns 0 on success, KDBG_ERR on failure. 52 * @param pFile The file 53 * @param off The file offset of the debug info. This is 0 if there isn't 54 * any specfic debug info section and the reader should start 55 * looking for debug info at the start of the file. 56 * @param cb The size of the debug info in the file. INT64_MAX if we don't 57 * know or there isn't any particular debug info section in the file. 58 * @param pLdrMod The associated loader module. This can be NULL. 59 * @param ppMod Where to store the module that's been opened. 60 * 61 * @remark This is NULL for the builtin readers. 62 */ 63 int (*pfnOpen)(PKDBGHLPFILE pFile, int64_t off, int64_t cb, PKLDRMOD pLdrMod, PKDBGMOD pMod); 64 65 /** 66 * Closes the module. 67 * 68 * This should free all resources associated with the module 69 * except the pMod which is freed by the caller. 70 * 71 * @returns IPRT status code. 72 * @param pMod The module. 73 */ 74 int (*pfnClose)(PKDBGMOD pMod); 75 76 /** 77 * Gets a symbol by segment:offset. 78 * This will be approximated to the nearest symbol if there is no exact match. 79 * 80 * @returns 0 on success. KLDR_ERR_* on failure. 81 * @param pMod The module. 82 * @param iSegment The segment this offset is relative to. 83 * The -1 segment is special, it means that the addres is relative to 84 * the image base. The image base is where the first bit of the image 85 * is mapped during load. 86 * @param off The offset into the segment. 87 * @param pSym Where to store the symbol details. 88 */ 89 int (*pfnQuerySymbol)(PKDBGMOD pMod, int32_t iSegment, KDBGADDR off, PKDBGSYMBOL pSym); 90 91 /** 92 * Gets a line number entry by segment:offset. 93 * This will be approximated to the nearest line number there is no exact match. 94 * 95 * @returns 0 on success. KLDR_ERR_* on failure. 96 * @param pMod The module. 97 * @param iSegment The segment this offset is relative to. 98 * The -1 segment is special, it means that the addres is relative to 99 * the image base. The image base is where the first bit of the image 100 * is mapped during load. 101 * @param off The offset into the segment. 102 * @param pLine Where to store the line number details. 103 */ 104 int (*pfnQueryLine)(PKDBGMOD pMod, int32_t iSegment, KDBGADDR uOffset, PKDBGLINE pLine); 105 106 } KDBGMODOPS; 107 /** Pointer to a module method table. */ 108 typedef KDBGMODOPS *PKDBGMODOPS; 109 /** Pointer to a const module method table. */ 110 typedef const KDBGMODOPS *PCKDBGMODOPS; 111 112 113 /** 114 * Internal representation of a debug module. 115 */ 116 typedef struct KDBGMOD 117 { 118 /** Magic value (KDBGMOD_MAGIC). */ 119 uint32_t u32Magic; 120 /** The handle to the module. (If closed, this is NIL_RTFILE.) */ 121 PKDBGHLPFILE pFile; 122 /** Pointer to the method table. */ 123 PCKDBGMODOPS pOps; 124 } KDBGMOD; 125 126 127 /** The magic value for the debug module structure. (Some dead english writer) */ 128 #define KDBGMOD_MAGIC 0x00000000 129 /** The magic value of a dead module structure. */ 130 #define KDBGMOD_MAGIC_DEAD 0x00000001 131 132 133 int kdbgModPEOpen(PKDBGHLPFILE pFile, KDBGADDR offHdr, const char *pszModulePath, PKDBGMOD *ppDbgMod); 134 int kdbgModWinDbgHelpOpen(PKDBGHLPFILE pFile, const char *pszModulePath, PKDBGMOD *ppDbgMod); 35 /** @name Built-in Debug Module Readers 36 * @{ */ 37 extern KDBGMODOPS const g_kDbgModWinDbgHelpOpen; 38 extern KDBGMODOPS const g_kDbgModLdr; 39 extern KDBGMODOPS const g_kDbgModCv8; 40 extern KDBGMODOPS const g_kDbgModDwarf; 41 extern KDBGMODOPS const g_kDbgModHll; 42 extern KDBGMODOPS const g_kDbgModStabs; 43 extern KDBGMODOPS const g_kDbgModSym; 44 extern KDBGMODOPS const g_kDbgModMapILink; 45 extern KDBGMODOPS const g_kDbgModMapMSLink; 46 extern KDBGMODOPS const g_kDbgModMapNm; 47 extern KDBGMODOPS const g_kDbgModMapWLink; 48 /** @} */ 135 49 136 50 #ifdef __cplusplus -
trunk/kStuff/kDbg/kDbgLine.cpp
r3537 r3541 57 57 * 58 58 * @returns 0 on success. 59 * @returns K DBG_ERR_INVALID_POINTER if a NULL pointer or an !KDBG_VALID_PTR() is passed in.59 * @returns KERR_INVALID_POINTER if a NULL pointer or an !KDBG_VALID_PTR() is passed in. 60 60 * 61 61 * @param pLine The line number to be freed. … … 64 64 { 65 65 if (!pLine) 66 return K DBG_ERR_INVALID_POINTER;67 kDbgAssertMsgReturn(KDBG_VALID_PTR(pLine), ("%p\n", pLine), K DBG_ERR_INVALID_POINTER);66 return KERR_INVALID_POINTER; 67 kDbgAssertMsgReturn(KDBG_VALID_PTR(pLine), ("%p\n", pLine), KERR_INVALID_POINTER); 68 68 69 69 kDbgHlpFree(pLine); -
trunk/kStuff/kDbg/kDbgModPE.cpp
r3537 r3541 151 151 } 152 152 #endif 153 rc = K DBG_ERR_NOT_IMPLEMENTED;153 rc = KERR_NOT_IMPLEMENTED; 154 154 } 155 155 return rc; … … 215 215 } 216 216 #endif 217 rc = K DBG_ERR_NOT_IMPLEMENTED;217 rc = KERR_NOT_IMPLEMENTED; 218 218 } 219 219 return rc; … … 235 235 //kDbgAssertMsgFailed(("SymInitialize failed: Err=%d rc=%Rrc\n", Err, rc)); 236 236 //return rc; 237 return KDBG_ERR_NOT_IMPLEMENTED; 238 } 239 240 241 /** 242 * Methods for a PE module. 243 */ 244 static const KDBGMODOPS g_kDbgModPeOps = 245 { 246 "PE", 247 kDbgModPeClose, 248 kDbgModPeQuerySymbol, 249 kDbgModPeQueryLine 250 }; 237 return KERR_NOT_IMPLEMENTED; 238 } 251 239 252 240 … … 286 274 */ 287 275 PKDBGMODPE pModPe = (PKDBGMODPE)kDbgHlpAlloc(KDBG_OFFSETOF(KDBGMODPE, aSections[FHdr.NumberOfSections + 2])); 288 kDbgAssertReturn(pModPe, K DBG_ERR_NO_MEMORY);276 kDbgAssertReturn(pModPe, KERR_NO_MEMORY); 289 277 pModPe->Core.u32Magic = KDBGMOD_MAGIC; 290 278 pModPe->Core.pOps = &g_kDbgModPeOps; … … 368 356 } 369 357 #endif 370 rc = K DBG_ERR_NOT_IMPLEMENTED;358 rc = KERR_NOT_IMPLEMENTED; 371 359 } 372 360 else … … 377 365 } 378 366 367 368 /** 369 * Methods for a PE module. 370 */ 371 const KDBGMODOPS g_kDbgModPeOps = 372 { 373 "PE", 374 kDbgModPeClose, 375 kDbgModPeQuerySymbol, 376 kDbgModPeQueryLine 377 }; 378 379 380 -
trunk/kStuff/kDbg/kDbgModWinDbgHelp.cpp
r3537 r3541 92 92 { 93 93 case 0: return 0; 94 default: return K DBG_ERR_GENERAL_FAILURE;94 default: return KERR_GENERAL_FAILURE; 95 95 } 96 96 } … … 323 323 } 324 324 else 325 rc = K DBG_ERR_GENERAL_FAILURE;325 rc = KERR_GENERAL_FAILURE; 326 326 } 327 327 else … … 344 344 uint32_t FileVersionMS = 0; 345 345 uint32_t FileVersionLS = 0; 346 int rc = K DBG_ERR_GENERAL_FAILURE;346 int rc = KERR_GENERAL_FAILURE; 347 347 static char s_szDbgHelp[] = "\\dbghelp.dll"; 348 348 if (GetCurrentDirectory((DWORD)(cchPath - sizeof(s_szDbgHelp) + 1), pszPath)) … … 597 597 */ 598 598 PKDBGMODDBGHELP pModDH = (PKDBGMODDBGHELP)kDbgHlpAlloc(KDBG_OFFSETOF(KDBGMODDBGHELP, aSections[FHdr.NumberOfSections + 2])); 599 kDbgAssertReturn(pModDH, K DBG_ERR_NO_MEMORY);599 kDbgAssertReturn(pModDH, KERR_NO_MEMORY); 600 600 pModDH->Core.u32Magic = KDBGMOD_MAGIC; 601 601 pModDH->Core.pOps = &g_kdbgModDHOps; -
trunk/kStuff/kDbg/kDbgModule.cpp
r3540 r3541 5 5 6 6 /* 7 * Copyright (c) 2006-2007 knut st. osmundsen <bird-src-spam@anduin.net> 8 * 9 * This file is part of kLIBC. 10 * 11 * kLIBC is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation; either version 2 of the License, or 7 * Copyright (c) 2007 knut st. osmundsen <bird-src-spam@anduin.net> 8 * 9 * 10 * This file is part of kStuff. 11 * 12 * kStuff is free software; you can redistribute it and/or modify 13 * it under the terms of the GNU Lesser General Public License as published 14 * by the Free Software Foundation; either version 2 of the License, or 14 15 * (at your option) any later version. 15 16 * 16 * k LIBCis distributed in the hope that it will be useful,17 * kStuff is distributed in the hope that it will be useful, 17 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details.20 * 21 * You should have received a copy of the GNU General Public License22 * along with k LIBC; if not, write to the Free Software20 * GNU Lesser General Public License for more details. 21 * 22 * You should have received a copy of the GNU Lesser General Public License 23 * along with kStuff; if not, write to the Free Software 23 24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 25 * 25 26 */ 27 26 28 27 29 … … 29 31 * Header Files * 30 32 *******************************************************************************/ 31 #include "kLdr.h"32 33 #include <k/kDbg.h> 34 #include <k/kErrors.h> 35 #include <string.h> 33 36 #include "kDbgInternal.h" 34 #include <kLdrModMZ.h>35 37 36 38 … … 38 40 * Global Variables * 39 41 *******************************************************************************/ 40 41 42 43 KDBG_DECL(int) kDbgModuleOpenFilePart(PKDBGHLPFILE pFile, int64_t off, int64_t cb, PKDBGMOD *ppDbgMod) 42 /** 43 * The built-in debug module readers. 44 */ 45 static PCKDBGMODOPS const g_aBuiltIns[] = 44 46 { 45 47 #if K_OS == K_OS_WINDOWS 46 /* 47 * If we're on Windows, let DbgHelp have a go first. 48 */ 49 if (!off) 48 &g_kDbgModWinDbgHelpOpen, 49 #endif 50 &g_kDbgModLdr, 51 &g_kDbgModCv8, 52 &g_kDbgModDwarf, 53 &g_kDbgModHll, 54 &g_kDbgModStabs, 55 &g_kDbgModSym, 56 &g_kDbgModMapILink, 57 &g_kDbgModMapMSLink, 58 &g_kDbgModMapNm, 59 &g_kDbgModMapWLink 60 }; 61 62 /** 63 * The debug module readers registered at runtime. 64 */ 65 static PKDBGMODOPS g_pHead = NULL; 66 67 68 /** 69 * Register a debug module reader with the kDbgModule component. 70 * 71 * Dynamically registered readers are kept in FIFO order, and external 72 * readers will be tried after the builtin ones. 73 * 74 * Like all other kDbg APIs serializing is left to the caller. 75 * 76 * @returns 0 on success. 77 * @returns KERR_INVALID_POINTER if pOps is missing bits. 78 * @returns KERR_INVALID_PARAMETER if pOps is already in the list. 79 * @param pOps The reader method table, kDbg takes owner ship of 80 * this. This must be writeable as the pNext pointer 81 * will be update. It must also stick around for as 82 * long as kDbg is in use. 83 */ 84 KDBG_DECL(int) kDbgModuleRegisterReader(PKDBGMODOPS pOps) 85 { 86 /* 87 * Validate input. 88 */ 89 kDbgAssertPtrReturn(pOps, KERR_INVALID_POINTER); 90 kDbgAssertPtrReturn(pOps->pszName, KERR_INVALID_POINTER); 91 kDbgAssertPtrReturn(pOps->pfnOpen, KERR_INVALID_POINTER); 92 kDbgAssertPtrReturn(pOps->pfnClose, KERR_INVALID_POINTER); 93 kDbgAssertPtrReturn(pOps->pfnQuerySymbol, KERR_INVALID_POINTER); 94 kDbgAssertPtrReturn(pOps->pfnQueryLine, KERR_INVALID_POINTER); 95 kDbgAssertPtrReturn(pOps->pszName2, KERR_INVALID_POINTER); 96 if (strcmp(pOps->pszName, pOps->pszName2)) 97 return KERR_INVALID_PARAMETER; 98 kDbgAssertReturn(pOps->pNext == NULL, KERR_INVALID_PARAMETER); 99 100 /* 101 * Link it into the list. 102 */ 103 if (!g_pHead) 104 g_pHead = pOps; 105 else 50 106 { 51 int rc = kdbgModWinDbgHelpOpen(pFile, ppDbgMod); 52 if (!rc) 53 return 0; 107 PKDBGMODOPS pPrev = g_pHead; 108 while (pPrev->pNext) 109 pPrev = pPrev->pNext; 110 kDbgAssertReturn(pPrev != pOps, KERR_INVALID_PARAMETER); 111 pPrev->pNext = pOps; 54 112 } 55 #endif 56 57 /* 58 * Probe the file for signatures we recognize. 59 */ 60 int64_t offHdr = 0; 61 union 113 return 0; 114 } 115 116 117 /** 118 * Deregister a debug module reader previously registered using 119 * the kDbgModuleRegisterReader API. 120 * 121 * Deregistering a reader does not mean that non of its functions 122 * will be called after successful return, it only means that it 123 * will no longer be subjected to new module. 124 * 125 * @returns 0 on success. 126 * @returns KERR_INVALID_POINTER if pOps isn't a valid pointer. 127 * @returns KERR_INVALID_PARAMETER if pOps wasn't registered. 128 * @param pOps The debug module method table to deregister. 129 */ 130 KDBG_DECL(int) kDbgModuleDeregisterReader(PKDBGMODOPS pOps) 131 { 132 /* 133 * Validate the pointer. 134 */ 135 kDbgAssertPtrReturn(pOps, KERR_INVALID_POINTER); 136 137 /* 138 * Find it in the list and unlink it. 139 */ 140 if (g_pHead == pOps) 141 g_pHead = pOps->pNext; 142 else 62 143 { 63 uint32_t au32[4]; 64 uint16_t au16[8]; 65 uint8_t ab[16]; 66 char 67 } Buf; 68 rc = kDbgHlpReadAt(pFile, &Buf, sizeof(Buf), off); 69 70 } 71 72 73 KDBG_DECL(int) kDbgModuleOpenFile(PKDBGHLPFILE pFile, PKDBGMOD *ppDbgMod) 74 { 75 return kDbgModuleOpenFilePart(pFile, 0, INT64_MAX, ppDbgMod); 76 } 77 78 79 KDBG_DECL(int) kDbgModuleOpenkLdrMod(PKLDRMOD pLdrMod, PKDBGMOD *ppDbgMod) 80 { 81 /* 82 * Enumerate the debug info, if nothing found check for a matching .pdb, 83 * .dbg, .sym or .map file. 84 */ 85 144 PKDBGMODOPS pPrev = g_pHead; 145 while (pPrev && pPrev->pNext != pOps) 146 pPrev = pPrev->pNext; 147 if (!pPrev) 148 return KERR_INVALID_PARAMETER; 149 pPrev->pNext = pOps->pNext; 150 } 151 pOps->pNext = NULL; 152 return 0; 153 } 154 155 156 /** 157 * Opens a debug module reader for the specified file or file section 158 * 159 * @returns kStuff status code. 160 * @param ppDbgMod Where to store the debug module reader handle. 161 * @param pFile The file reader. 162 * @param off The offset of the file section. If the entire file, pass 0. 163 * @param cb The size of the file section. If the entire file, pass KFOFF_MAX. 164 * @param pLdrMod Associated kLdr module that the kDbg component can use to 165 * verify and suplement the debug info found in the file specified 166 * by pszFilename. The module will be used by kDbg for as long as 167 * the returned kDbg module remains open. 168 * This is an optional parameter, pass NULL if no kLdr module at hand. 169 */ 170 KDBG_DECL(int) kDbgModuleOpenFilePart(PKDBGMOD *ppDbgMod, PKDBGHLPFILE pFile, KFOFF off, KFOFF cb, struct KLDRMOD *pLdrMod) 171 { 172 /* 173 * Validate input. 174 */ 175 kDbgAssertPtrReturn(ppDbgMod, KERR_INVALID_POINTER); 176 kDbgAssertPtrReturn(pFile, KERR_INVALID_POINTER); 177 kDbgAssertPtrNullReturn(pLdrMod, KERR_INVALID_POINTER); 178 kDbgAssertMsgReturn(off >= 0 && off < KFOFF_MAX, (KFOFF_PRI "\n", off), KERR_INVALID_OFFSET); 179 kDbgAssertMsgReturn(cb >= 0 && cb <= KFOFF_MAX, (KFOFF_PRI "\n", cb), KERR_INVALID_SIZE); 180 kDbgAssertMsgReturn(off + cb > off, ("off=" KFOFF_PRI " cb=" KFOFF_PRI "\n", off, cb), KERR_INVALID_RANGE); 181 *ppDbgMod = NULL; 182 183 /* 184 * Walk the built-in table and the list of registered readers 185 * and let each of them have a go at the file. Stop and return 186 * on the first one returning successfully. 187 */ 188 int rc = KDBG_ERR_UNKOWN_FORMAT; 189 for (KSIZE i = 0; i < K_ELEMENTS(g_aBuiltIns); i++) 190 if (g_aBuiltIns[i]->pfnOpen) 191 { 192 int rc2 = g_aBuiltIns[i]->pfnOpen(ppDbgMod, pFile, off, cb, pLdrMod); 193 if (!rc) 194 return 0; 195 if (rc2 != KDBG_ERR_UNKOWN_FORMAT && rc == KDBG_ERR_UNKOWN_FORMAT) 196 rc = rc2; 197 } 198 199 for (PKDBGMODOPS pCur = g_pHead; pCur; pCur = pCur->pNext) 200 if (g_aBuiltIns[i]->pfnOpen) 201 { 202 int rc2 = g_aBuiltIns[i]->pfnOpen(ppDbgMod, pFile, off, cb, pLdrMod); 203 if (!rc) 204 return 0; 205 if (rc2 != KDBG_ERR_UNKOWN_FORMAT && rc == KDBG_ERR_UNKOWN_FORMAT) 206 rc = rc2; 207 } 208 return rc; 209 } 210 211 212 /** 213 * Opens a debug module reader for the specified file. 214 * 215 * @returns kStuff status code. 216 * @param ppDbgMod Where to store the debug module reader handle. 217 * @param pFile The file reader. 218 * @param pLdrMod Associated kLdr module that the kDbg component can use to 219 * verify and suplement the debug info found in the file specified 220 * by pszFilename. The module will be used by kDbg for as long as 221 * the returned kDbg module remains open. 222 * This is an optional parameter, pass NULL if no kLdr module at hand. 223 */ 224 KDBG_DECL(int) kDbgModuleOpenFile(PKDBGMOD *ppDbgMod, PKDBGHLPFILE pFile, struct KLDRMOD *pLdrMod) 225 { 226 return kDbgModuleOpenFilePart(ppDbgMod, pFile, 0, KFOFF_MAX, pLdrMod); 86 227 } 87 228 … … 90 231 * Opens the debug info for a specified executable module. 91 232 * 92 * @returns IPRT status code. 93 * @param pszModulePath The path to the executable module. 233 * @returns kStuff status code. 94 234 * @param ppDbgMod Where to store the debug module handle. 95 */ 96 KDBG_DECL(int) kDbgModuleOpen(const char *pszModulePath, PKDBGMOD *ppDbgMod) 235 * @param pszFilename The name of the file containing debug info and/or which 236 * debug info is wanted. 237 * @param pLdrMod Associated kLdr module that the kDbg component can use to 238 * verify and suplement the debug info found in the file specified 239 * by pszFilename. The module will be used by kDbg for as long as 240 * the returned kDbg module remains open. 241 * This is an optional parameter, pass NULL if no kLdr module at hand. 242 */ 243 KDBG_DECL(int) kDbgModuleOpen(PKDBGMOD *ppDbgMod, const char *pszFilename, struct KLDRMOD *pLdrMod) 97 244 { 98 245 /* 99 246 * Validate input. 100 247 */ 101 kDbgAssertPtrReturn(pszModulePath, KDBG_ERR_INVALID_POINTER); 102 kDbgAssertMsgReturn(*pszModulePath, ("%p\n", pszModulePath), KDBG_ERR_INVALID_PARAMETER); 103 kDbgAssertPtrReturn(ppDbgMod, KDBG_ERR_INVALID_POINTER); 248 kDbgAssertPtrReturn(ppDbgMod, KERR_INVALID_POINTER); 249 kDbgAssertPtrReturn(pszFilename, KERR_INVALID_POINTER); 250 kDbgAssertMsgReturn(*pszFilename, ("%p\n", pszFilename), KERR_INVALID_PARAMETER); 251 kDbgAssertPtrNullReturn(pLdrMod, KERR_INVALID_POINTER); 104 252 *ppDbgMod = NULL; 105 253 … … 108 256 */ 109 257 PKDBGHLPFILE pFile; 110 int rc = kDbgHlpOpenRO(psz ModulePath, &pFile);258 int rc = kDbgHlpOpenRO(pszFilename, &pFile); 111 259 if (rc) 112 260 return rc; 113 rc = kDbgModuleOpenFile (pFile, ppDbgMod);261 rc = kDbgModuleOpenFilePart(ppDbgMod, pFile, 0, KFOFF_MAX, pLdrMod); 114 262 if (rc) 115 {116 263 kDbgHlpClose(pFile); 117 118 /*119 * Let kLdr have a shot at it, if it's a binary it may contain120 * some debug sections or a link to an external debug file.121 */122 PKLDRMOD pLdrMod;123 int rc2 = kLdrModOpen(pszModulePath, *pLdrMod);124 if (!rc2)125 {126 rc = kDbgModuleOpenkLdrMod(pLdrMod, ppDbgMod);127 if (rc)128 kLdrModClose(pLdrMod);129 }130 }131 132 264 return rc; 133 265 } … … 159 291 { 160 292 if (!kdbgModIsValid(pMod)) 161 return K DBG_ERR_INVALID_PARAMETER;293 return KERR_INVALID_PARAMETER; 162 294 163 295 int rc = pMod->pOps->pfnClose(pMod); … … 184 316 { 185 317 if (!kdbgModIsValid(pMod)) 186 return K DBG_ERR_INVALID_PARAMETER;187 kDbgAssertPtrReturn(pSym, K DBG_ERR_INVALID_POINTER);318 return KERR_INVALID_PARAMETER; 319 kDbgAssertPtrReturn(pSym, KERR_INVALID_POINTER); 188 320 189 321 return pMod->pOps->pfnQuerySymbol(pMod, iSegment, off, pSym); … … 207 339 KDBG_DECL(int) kDbgModuleQuerySymbolA(PKDBGMOD pMod, int32_t iSegment, KDBGADDR off, PPKDBGSYMBOL ppSym) 208 340 { 209 kDbgAssertPtrReturn(ppSym, K DBG_ERR_INVALID_POINTER);341 kDbgAssertPtrReturn(ppSym, KERR_INVALID_POINTER); 210 342 211 343 KDBGSYMBOL Sym; … … 215 347 *ppSym = kDbgSymbolDup(&Sym); 216 348 if (!*ppSym) 217 rc = K DBG_ERR_NO_MEMORY;349 rc = KERR_NO_MEMORY; 218 350 } 219 351 else … … 239 371 { 240 372 if (!kdbgModIsValid(pMod)) 241 return K DBG_ERR_INVALID_PARAMETER;242 kDbgAssertPtrReturn(pLine, K DBG_ERR_INVALID_POINTER);373 return KERR_INVALID_PARAMETER; 374 kDbgAssertPtrReturn(pLine, KERR_INVALID_POINTER); 243 375 244 376 return pMod->pOps->pfnQueryLine(pMod, iSegment, off, pLine); … … 262 394 KDBG_DECL(int) kDbgModuleQueryLineA(PKDBGMOD pMod, int32_t iSegment, KDBGADDR off, PPKDBGLINE ppLine) 263 395 { 264 kDbgAssertPtrReturn(ppLine, K DBG_ERR_INVALID_POINTER);396 kDbgAssertPtrReturn(ppLine, KERR_INVALID_POINTER); 265 397 266 398 KDBGLINE Line; … … 270 402 *ppLine = kDbgLineDup(&Line); 271 403 if (!*ppLine) 272 rc = K DBG_ERR_NO_MEMORY;404 rc = KERR_NO_MEMORY; 273 405 } 274 406 else -
trunk/kStuff/kDbg/kDbgSymbol.cpp
r3537 r3541 56 56 * 57 57 * @returns 0 on success. 58 * @returns K DBG_ERR_INVALID_POINTER if a NULL pointer or an !KDBG_VALID_PTR() is passed in.58 * @returns KERR_INVALID_POINTER if a NULL pointer or an !KDBG_VALID_PTR() is passed in. 59 59 * 60 60 * @param pSymbol The symbol to be freed. … … 63 63 { 64 64 if (!pSymbol) 65 return K DBG_ERR_INVALID_POINTER;66 kDbgAssertPtrReturn(pSymbol, K DBG_ERR_INVALID_POINTER);65 return KERR_INVALID_POINTER; 66 kDbgAssertPtrReturn(pSymbol, KERR_INVALID_POINTER); 67 67 68 68 kDbgHlpFree(pSymbol);
Note:
See TracChangeset
for help on using the changeset viewer.