| 1 | /* |
| 2 | * Copyright (c) 2018 Virtuozzo International GmbH |
| 3 | * |
| 4 | * This work is licensed under the terms of the GNU GPL, version 2 or later. |
| 5 | * |
| 6 | */ |
| 7 | |
| 8 | #ifndef PDB_H |
| 9 | #define PDB_H |
| 10 | |
| 11 | |
| 12 | #ifndef _WIN32 |
| 13 | typedef struct GUID { |
| 14 | unsigned int Data1; |
| 15 | unsigned short Data2; |
| 16 | unsigned short Data3; |
| 17 | unsigned char Data4[8]; |
| 18 | } GUID; |
| 19 | #endif |
| 20 | |
| 21 | struct PDB_FILE { |
| 22 | uint32_t size; |
| 23 | uint32_t unknown; |
| 24 | }; |
| 25 | |
| 26 | typedef struct PDB_DS_HEADER { |
| 27 | char signature[32]; |
| 28 | uint32_t block_size; |
| 29 | uint32_t unknown1; |
| 30 | uint32_t num_pages; |
| 31 | uint32_t toc_size; |
| 32 | uint32_t unknown2; |
| 33 | uint32_t toc_page; |
| 34 | } PDB_DS_HEADER; |
| 35 | |
| 36 | typedef struct PDB_DS_TOC { |
| 37 | uint32_t num_files; |
| 38 | uint32_t file_size[1]; |
| 39 | } PDB_DS_TOC; |
| 40 | |
| 41 | typedef struct PDB_DS_ROOT { |
| 42 | uint32_t Version; |
| 43 | uint32_t TimeDateStamp; |
| 44 | uint32_t Age; |
| 45 | GUID guid; |
| 46 | uint32_t cbNames; |
| 47 | char names[1]; |
| 48 | } PDB_DS_ROOT; |
| 49 | |
| 50 | typedef struct PDB_TYPES_OLD { |
| 51 | uint32_t version; |
| 52 | uint16_t first_index; |
| 53 | uint16_t last_index; |
| 54 | uint32_t type_size; |
| 55 | uint16_t file; |
| 56 | uint16_t pad; |
| 57 | } PDB_TYPES_OLD; |
| 58 | |
| 59 | typedef struct PDB_TYPES { |
| 60 | uint32_t version; |
| 61 | uint32_t type_offset; |
| 62 | uint32_t first_index; |
| 63 | uint32_t last_index; |
| 64 | uint32_t type_size; |
| 65 | uint16_t file; |
| 66 | uint16_t pad; |
| 67 | uint32_t hash_size; |
| 68 | uint32_t hash_base; |
| 69 | uint32_t hash_offset; |
| 70 | uint32_t hash_len; |
| 71 | uint32_t search_offset; |
| 72 | uint32_t search_len; |
| 73 | uint32_t unknown_offset; |
| 74 | uint32_t unknown_len; |
| 75 | } PDB_TYPES; |
| 76 | |
| 77 | typedef struct PDB_SYMBOL_RANGE { |
| 78 | uint16_t segment; |
| 79 | uint16_t pad1; |
| 80 | uint32_t offset; |
| 81 | uint32_t size; |
| 82 | uint32_t characteristics; |
| 83 | uint16_t index; |
| 84 | uint16_t pad2; |
| 85 | } PDB_SYMBOL_RANGE; |
| 86 | |
| 87 | typedef struct PDB_SYMBOL_RANGE_EX { |
| 88 | uint16_t segment; |
| 89 | uint16_t pad1; |
| 90 | uint32_t offset; |
| 91 | uint32_t size; |
| 92 | uint32_t characteristics; |
| 93 | uint16_t index; |
| 94 | uint16_t pad2; |
| 95 | uint32_t timestamp; |
| 96 | uint32_t unknown; |
| 97 | } PDB_SYMBOL_RANGE_EX; |
| 98 | |
| 99 | typedef struct PDB_SYMBOL_FILE { |
| 100 | uint32_t unknown1; |
| 101 | PDB_SYMBOL_RANGE range; |
| 102 | uint16_t flag; |
| 103 | uint16_t file; |
| 104 | uint32_t symbol_size; |
| 105 | uint32_t lineno_size; |
| 106 | uint32_t unknown2; |
| 107 | uint32_t nSrcFiles; |
| 108 | uint32_t attribute; |
| 109 | char filename[1]; |
| 110 | } PDB_SYMBOL_FILE; |
| 111 | |
| 112 | typedef struct PDB_SYMBOL_FILE_EX { |
| 113 | uint32_t unknown1; |
| 114 | PDB_SYMBOL_RANGE_EX range; |
| 115 | uint16_t flag; |
| 116 | uint16_t file; |
| 117 | uint32_t symbol_size; |
| 118 | uint32_t lineno_size; |
| 119 | uint32_t unknown2; |
| 120 | uint32_t nSrcFiles; |
| 121 | uint32_t attribute; |
| 122 | uint32_t reserved[2]; |
| 123 | char filename[1]; |
| 124 | } PDB_SYMBOL_FILE_EX; |
| 125 | |
| 126 | typedef struct PDB_SYMBOL_SOURCE { |
| 127 | uint16_t nModules; |
| 128 | uint16_t nSrcFiles; |
| 129 | uint16_t table[1]; |
| 130 | } PDB_SYMBOL_SOURCE; |
| 131 | |
| 132 | typedef struct PDB_SYMBOL_IMPORT { |
| 133 | uint32_t unknown1; |
| 134 | uint32_t unknown2; |
| 135 | uint32_t TimeDateStamp; |
| 136 | uint32_t Age; |
| 137 | char filename[1]; |
| 138 | } PDB_SYMBOL_IMPORT; |
| 139 | |
| 140 | typedef struct PDB_SYMBOLS_OLD { |
| 141 | uint16_t hash1_file; |
| 142 | uint16_t hash2_file; |
| 143 | uint16_t gsym_file; |
| 144 | uint16_t pad; |
| 145 | uint32_t module_size; |
| 146 | uint32_t offset_size; |
| 147 | uint32_t hash_size; |
| 148 | uint32_t srcmodule_size; |
| 149 | } PDB_SYMBOLS_OLD; |
| 150 | |
| 151 | typedef struct PDB_SYMBOLS { |
| 152 | uint32_t signature; |
| 153 | uint32_t version; |
| 154 | uint32_t unknown; |
| 155 | uint32_t hash1_file; |
| 156 | uint32_t hash2_file; |
| 157 | uint16_t gsym_file; |
| 158 | uint16_t unknown1; |
| 159 | uint32_t module_size; |
| 160 | uint32_t offset_size; |
| 161 | uint32_t hash_size; |
| 162 | uint32_t srcmodule_size; |
| 163 | uint32_t pdbimport_size; |
| 164 | uint32_t resvd0; |
| 165 | uint32_t stream_index_size; |
| 166 | uint32_t unknown2_size; |
| 167 | uint16_t resvd3; |
| 168 | uint16_t machine; |
| 169 | uint32_t resvd4; |
| 170 | } PDB_SYMBOLS; |
| 171 | |
| 172 | typedef struct { |
| 173 | uint16_t FPO; |
| 174 | uint16_t unk0; |
| 175 | uint16_t unk1; |
| 176 | uint16_t unk2; |
| 177 | uint16_t unk3; |
| 178 | uint16_t segments; |
| 179 | } PDB_STREAM_INDEXES_OLD; |
| 180 | |
| 181 | typedef struct { |
| 182 | uint16_t FPO; |
| 183 | uint16_t unk0; |
| 184 | uint16_t unk1; |
| 185 | uint16_t unk2; |
| 186 | uint16_t unk3; |
| 187 | uint16_t segments; |
| 188 | uint16_t unk4; |
| 189 | uint16_t unk5; |
| 190 | uint16_t unk6; |
| 191 | uint16_t FPO_EXT; |
| 192 | uint16_t unk7; |
| 193 | } PDB_STREAM_INDEXES; |
| 194 | |
| 195 | union codeview_symbol { |
| 196 | struct { |
| 197 | int16_t len; |
| 198 | int16_t id; |
| 199 | } generic; |
| 200 | |
| 201 | struct { |
| 202 | int16_t len; |
| 203 | int16_t id; |
| 204 | uint32_t symtype; |
| 205 | uint32_t offset; |
| 206 | uint16_t segment; |
| 207 | char name[1]; |
| 208 | } public_v3; |
| 209 | }; |
| 210 | |
| 211 | #define S_PUB_V3 0x110E |
| 212 | |
| 213 | typedef struct pdb_seg { |
| 214 | uint32_t dword[8]; |
| 215 | } __attribute__ ((packed)) pdb_seg; |
| 216 | |
| 217 | #define IMAGE_FILE_MACHINE_I386 0x014c |
| 218 | #define IMAGE_FILE_MACHINE_AMD64 0x8664 |
| 219 | |
| 220 | struct pdb_reader { |
| 221 | GMappedFile *gmf; |
| 222 | size_t file_size; |
| 223 | struct { |
| 224 | PDB_DS_HEADER *header; |
| 225 | PDB_DS_TOC *toc; |
| 226 | PDB_DS_ROOT *root; |
| 227 | } ds; |
| 228 | uint32_t file_used[1024]; |
| 229 | PDB_SYMBOLS *symbols; |
| 230 | uint16_t segments; |
| 231 | uint8_t *modimage; |
| 232 | char *segs; |
| 233 | size_t segs_size; |
| 234 | }; |
| 235 | |
| 236 | bool pdb_init_from_file(const char *name, struct pdb_reader *reader); |
| 237 | void pdb_exit(struct pdb_reader *reader); |
| 238 | uint64_t pdb_resolve(uint64_t img_base, struct pdb_reader *r, const char *name); |
| 239 | uint64_t pdb_find_public_v3_symbol(struct pdb_reader *reader, const char *name); |
| 240 | |
| 241 | #endif /* PDB_H */ |