15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Copyright (c) 2008, Google Inc. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * All rights reserved. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Redistribution and use in source and binary forms, with or without 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * modification, are permitted provided that the following conditions are 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * met: 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * Redistributions of source code must retain the above copyright 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * notice, this list of conditions and the following disclaimer. 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * Redistributions in binary form must reproduce the above 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in the documentation and/or other materials provided with the 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * distribution. 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * Neither the name of Google Inc. nor the names of its 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * contributors may be used to endorse or promote products derived from 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * this software without specific prior written permission. 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * --- 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Author: David Vitek 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Dump function addresses using Microsoft debug symbols. This works 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * on PDB files. Note that this program will download symbols to 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * c:\websymbols without asking. 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WIN32_LEAN_AND_MEAN 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define _CRT_SECURE_NO_WARNINGS 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define _CRT_SECURE_NO_DEPRECATE 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h> 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h> 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> // for _strdup 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h> 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <dbghelp.h> 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Unfortunately, there is no versioning info in dbghelp.h so I can 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// tell whether it has an old-style (circa VC7.1) IMAGEHLP_MODULE64 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// struct, with only a few fields, or a new-style (circa VC8) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// IMAGEHLP_MODULE64, with lots of fields. These fields are just used 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for debugging, so it's fine to just assume the smaller struct, but 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for most people, using a modern MSVC, the full struct is available. 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If you are one of those people and would like this extra debugging 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// info, you can uncomment the line below. 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//#define VC8_OR_ABOVE 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SEARCH_CAP (1024*1024) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WEBSYM "SRV*c:\\websymbols*http://msdl.microsoft.com/download/symbols" 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *name; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ULONG64 addr; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ULONG flags; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} SYM; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct { 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ULONG64 module_base; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SYM *syms; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD syms_len; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD syms_cap; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} SYM_CONTEXT; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int sym_cmp(const void *_s1, const void *_s2) { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SYM *s1 = (const SYM *)_s1; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SYM *s2 = (const SYM *)_s2; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (s1->addr < s2->addr) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (s1->addr > s2->addr) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static BOOL CALLBACK EnumSymProc(PSYMBOL_INFO symbol_info, 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ULONG symbol_size, 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PVOID user_context) { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SYM_CONTEXT *ctx = (SYM_CONTEXT*)user_context; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (symbol_info->Address < ctx->module_base || 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (symbol_info->Flags & SYMFLAG_TLSREL)) { 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRUE; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctx->syms_len == ctx->syms_cap) { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ctx->syms_cap) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctx->syms_cap++; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctx->syms_cap *= 2; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctx->syms = realloc(ctx->syms, sizeof(ctx->syms[0]) * ctx->syms_cap); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctx->syms[ctx->syms_len].name = _strdup(symbol_info->Name); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctx->syms[ctx->syms_len].addr = symbol_info->Address; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctx->syms[ctx->syms_len].flags = symbol_info->Flags; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctx->syms_len++; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRUE; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void MaybePrint(const char* var, const char* description) { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (var[0]) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("%s: %s\n", description, var); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void PrintAvailability(BOOL var, const char *description) { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("s: %s\n", description, (var ? "Available" : "Not available")); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void ShowSymbolInfo(HANDLE process, ULONG64 module_base) { 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Get module information. */ 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IMAGEHLP_MODULE64 module_info; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BOOL getmoduleinfo_rv; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Load Address: %I64x\n", module_base); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(&module_info, 0, sizeof(module_info)); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) module_info.SizeOfStruct = sizeof(module_info); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getmoduleinfo_rv = SymGetModuleInfo64(process, module_base, &module_info); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!getmoduleinfo_rv) { 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Error: SymGetModuleInfo64() failed. Error code: %u\n", 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetLastError()); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Display information about symbols, based on kind of symbol. */ 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (module_info.SymType) { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SymNone: 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf(("No symbols available for the module.\n")); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SymExport: 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf(("Loaded symbols: Exports\n")); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SymCoff: 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf(("Loaded symbols: COFF\n")); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SymCv: 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf(("Loaded symbols: CodeView\n")); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SymSym: 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf(("Loaded symbols: SYM\n")); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SymVirtual: 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf(("Loaded symbols: Virtual\n")); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SymPdb: 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf(("Loaded symbols: PDB\n")); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SymDia: 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf(("Loaded symbols: DIA\n")); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SymDeferred: 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf(("Loaded symbols: Deferred\n")); /* not actually loaded */ 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf(("Loaded symbols: Unknown format.\n")); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MaybePrint("Image name", module_info.ImageName); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MaybePrint("Loaded image name", module_info.LoadedImageName); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef VC8_OR_ABOVE /* TODO(csilvers): figure out how to tell */ 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MaybePrint("PDB file name", module_info.LoadedPdbName); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (module_info.PdbUnmatched || module_info.DbgUnmatched) { 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This can only happen if the debug information is contained in a 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * separate file (.DBG or .PDB) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf(("Warning: Unmatched symbols.\n")); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Contents */ 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef VC8_OR_ABOVE /* TODO(csilvers): figure out how to tell */ 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintAvailability("Line numbers", module_info.LineNumbers); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintAvailability("Global symbols", module_info.GlobalSymbols); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintAvailability("Type information", module_info.TypeInfo); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int main(int argc, char *argv[]) { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD error; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HANDLE process; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ULONG64 module_base; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SYM_CONTEXT ctx; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* search; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* filename = NULL; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = 0; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* We may add SYMOPT_UNDNAME if --demangle is specified: */ 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD symopts = SYMOPT_DEFERRED_LOADS | SYMOPT_DEBUG; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 1; i < argc; i++) { 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (strcmp(argv[i], "--demangle") == 0 || strcmp(argv[i], "-C") == 0) { 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) symopts |= SYMOPT_UNDNAME; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i != argc - 1) { 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "usage: nm-pdb [-C|--demangle] <module or filename>\n"); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exit(1); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filename = argv[i]; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process = GetCurrentProcess(); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!SymInitialize(process, NULL, FALSE)) { 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error = GetLastError(); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "SymInitialize returned error : %d\n", error); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) search = malloc(SEARCH_CAP); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SymGetSearchPath(process, search, SEARCH_CAP)) { 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (strlen(search) + sizeof(";" WEBSYM) > SEARCH_CAP) { 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "Search path too long\n"); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SymCleanup(process); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strcat(search, ";" WEBSYM); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error = GetLastError(); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "SymGetSearchPath returned error : %d\n", error); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = 1; /* An error, but not a fatal one */ 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strcpy(search, WEBSYM); /* Use a default value */ 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!SymSetSearchPath(process, search)) { 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error = GetLastError(); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "SymSetSearchPath returned error : %d\n", error); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = 1; /* An error, but not a fatal one */ 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SymSetOptions(symopts); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) module_base = SymLoadModuleEx(process, NULL, filename, NULL, 0, 0, NULL, 0); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!module_base) { 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* SymLoadModuleEx failed */ 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error = GetLastError(); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "SymLoadModuleEx returned error : %d for %s\n", 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error, filename); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SymCleanup(process); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ShowSymbolInfo(process, module_base); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(&ctx, 0, sizeof(ctx)); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctx.module_base = module_base; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!SymEnumSymbols(process, module_base, NULL, EnumSymProc, &ctx)) { 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error = GetLastError(); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "SymEnumSymbols returned error: %d\n", error); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = 1; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD j; 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) qsort(ctx.syms, ctx.syms_len, sizeof(ctx.syms[0]), sym_cmp); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (j = 0; j < ctx.syms_len; j++) { 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("%016I64x X %s\n", ctx.syms[j].addr, ctx.syms[j].name); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* In a perfect world, maybe we'd clean up ctx's memory? */ 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SymUnloadModule64(process, module_base); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SymCleanup(process); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 267