| ... | ... | @@ -5,6 +5,7 @@ const math = std.math; |
| 5 | 5 | const mem = std.mem; |
| 6 | 6 | const os = std.os; |
| 7 | 7 | const warn = std.debug.warn; |
| 8 | const Coff = std.coff.Coff; |
| 8 | 9 | |
| 9 | 10 | const ArrayList = std.ArrayList; |
| 10 | 11 | |
| ... | ... | @@ -20,8 +21,8 @@ const DbiStreamHeader = packed struct { |
| 20 | 21 | SymRecordStream: u16, |
| 21 | 22 | PdbDllRbld: u16, |
| 22 | 23 | ModInfoSize: u32, |
| 23 | | SectionContributionSize: i32, |
| 24 | | SectionMapSize: i32, |
| 24 | SectionContributionSize: u32, |
| 25 | SectionMapSize: u32, |
| 25 | 26 | SourceInfoSize: i32, |
| 26 | 27 | TypeServerSize: i32, |
| 27 | 28 | MFCTypeServerIndex: u32, |
| ... | ... | @@ -35,8 +36,8 @@ const DbiStreamHeader = packed struct { |
| 35 | 36 | const SectionContribEntry = packed struct { |
| 36 | 37 | Section: u16, |
| 37 | 38 | Padding1: [2]u8, |
| 38 | | Offset: i32, |
| 39 | | Size: i32, |
| 39 | Offset: u32, |
| 40 | Size: u32, |
| 40 | 41 | Characteristics: u32, |
| 41 | 42 | ModuleIndex: u16, |
| 42 | 43 | Padding2: [2]u8, |
| ... | ... | @@ -62,6 +63,22 @@ const ModInfo = packed struct { |
| 62 | 63 | //ObjFileName: char[], |
| 63 | 64 | }; |
| 64 | 65 | |
| 66 | const SectionMapHeader = packed struct { |
| 67 | Count: u16, /// Number of segment descriptors |
| 68 | LogCount: u16, /// Number of logical segment descriptors |
| 69 | }; |
| 70 | |
| 71 | const SectionMapEntry = packed struct { |
| 72 | Flags: u16 , /// See the SectionMapEntryFlags enum below. |
| 73 | Ovl: u16 , /// Logical overlay number |
| 74 | Group: u16 , /// Group index into descriptor array. |
| 75 | Frame: u16 , |
| 76 | SectionName: u16 , /// Byte index of segment / group name in string table, or 0xFFFF. |
| 77 | ClassName: u16 , /// Byte index of class in string table, or 0xFFFF. |
| 78 | Offset: u32 , /// Byte offset of the logical segment within physical segment. If group is set in flags, this is the offset of the group. |
| 79 | SectionLength: u32 , /// Byte count of the segment or group. |
| 80 | }; |
| 81 | |
| 65 | 82 | pub const StreamType = enum(u16) { |
| 66 | 83 | Pdb = 1, |
| 67 | 84 | Tpi = 2, |
| ... | ... | @@ -69,24 +86,306 @@ pub const StreamType = enum(u16) { |
| 69 | 86 | Ipi = 4, |
| 70 | 87 | }; |
| 71 | 88 | |
| 89 | const Module = struct { |
| 90 | mod_info: ModInfo, |
| 91 | module_name: []u8, |
| 92 | obj_file_name: []u8, |
| 93 | }; |
| 94 | |
| 95 | /// Distinguishes individual records in the Symbols subsection of a .debug$S |
| 96 | /// section. Equivalent to SYM_ENUM_e in cvinfo.h. |
| 97 | pub const SymbolRecordKind = enum(u16) { |
| 98 | InlineesSym = 4456, |
| 99 | ScopeEndSym = 6, |
| 100 | InlineSiteEnd = 4430, |
| 101 | ProcEnd = 4431, |
| 102 | Thunk32Sym = 4354, |
| 103 | TrampolineSym = 4396, |
| 104 | SectionSym = 4406, |
| 105 | CoffGroupSym = 4407, |
| 106 | ExportSym = 4408, |
| 107 | ProcSym = 4367, |
| 108 | GlobalProcSym = 4368, |
| 109 | ProcIdSym = 4422, |
| 110 | GlobalProcIdSym = 4423, |
| 111 | DPCProcSym = 4437, |
| 112 | DPCProcIdSym = 4438, |
| 113 | RegisterSym = 4358, |
| 114 | PublicSym32 = 4366, |
| 115 | ProcRefSym = 4389, |
| 116 | LocalProcRef = 4391, |
| 117 | EnvBlockSym = 4413, |
| 118 | InlineSiteSym = 4429, |
| 119 | LocalSym = 4414, |
| 120 | DefRangeSym = 4415, |
| 121 | DefRangeSubfieldSym = 4416, |
| 122 | DefRangeRegisterSym = 4417, |
| 123 | DefRangeFramePointerRelSym = 4418, |
| 124 | DefRangeSubfieldRegisterSym = 4419, |
| 125 | DefRangeFramePointerRelFullScopeSym = 4420, |
| 126 | DefRangeRegisterRelSym = 4421, |
| 127 | BlockSym = 4355, |
| 128 | LabelSym = 4357, |
| 129 | ObjNameSym = 4353, |
| 130 | Compile2Sym = 4374, |
| 131 | Compile3Sym = 4412, |
| 132 | FrameProcSym = 4114, |
| 133 | CallSiteInfoSym = 4409, |
| 134 | FileStaticSym = 4435, |
| 135 | HeapAllocationSiteSym = 4446, |
| 136 | FrameCookieSym = 4410, |
| 137 | CallerSym = 4442, |
| 138 | CalleeSym = 4443, |
| 139 | UDTSym = 4360, |
| 140 | CobolUDT = 4361, |
| 141 | BuildInfoSym = 4428, |
| 142 | BPRelativeSym = 4363, |
| 143 | RegRelativeSym = 4369, |
| 144 | ConstantSym = 4359, |
| 145 | ManagedConstant = 4397, |
| 146 | DataSym = 4364, |
| 147 | GlobalData = 4365, |
| 148 | ManagedLocalData = 4380, |
| 149 | ManagedGlobalData = 4381, |
| 150 | ThreadLocalDataSym = 4370, |
| 151 | GlobalTLS = 4371, |
| 152 | }; |
| 153 | |
| 154 | /// Duplicate copy of SymbolRecordKind, but using the official CV names. Useful |
| 155 | /// for reference purposes and when dealing with unknown record types. |
| 156 | pub const SymbolKind = enum(u16) { |
| 157 | S_COMPILE = 1, |
| 158 | S_REGISTER_16t = 2, |
| 159 | S_CONSTANT_16t = 3, |
| 160 | S_UDT_16t = 4, |
| 161 | S_SSEARCH = 5, |
| 162 | S_SKIP = 7, |
| 163 | S_CVRESERVE = 8, |
| 164 | S_OBJNAME_ST = 9, |
| 165 | S_ENDARG = 10, |
| 166 | S_COBOLUDT_16t = 11, |
| 167 | S_MANYREG_16t = 12, |
| 168 | S_RETURN = 13, |
| 169 | S_ENTRYTHIS = 14, |
| 170 | S_BPREL16 = 256, |
| 171 | S_LDATA16 = 257, |
| 172 | S_GDATA16 = 258, |
| 173 | S_PUB16 = 259, |
| 174 | S_LPROC16 = 260, |
| 175 | S_GPROC16 = 261, |
| 176 | S_THUNK16 = 262, |
| 177 | S_BLOCK16 = 263, |
| 178 | S_WITH16 = 264, |
| 179 | S_LABEL16 = 265, |
| 180 | S_CEXMODEL16 = 266, |
| 181 | S_VFTABLE16 = 267, |
| 182 | S_REGREL16 = 268, |
| 183 | S_BPREL32_16t = 512, |
| 184 | S_LDATA32_16t = 513, |
| 185 | S_GDATA32_16t = 514, |
| 186 | S_PUB32_16t = 515, |
| 187 | S_LPROC32_16t = 516, |
| 188 | S_GPROC32_16t = 517, |
| 189 | S_THUNK32_ST = 518, |
| 190 | S_BLOCK32_ST = 519, |
| 191 | S_WITH32_ST = 520, |
| 192 | S_LABEL32_ST = 521, |
| 193 | S_CEXMODEL32 = 522, |
| 194 | S_VFTABLE32_16t = 523, |
| 195 | S_REGREL32_16t = 524, |
| 196 | S_LTHREAD32_16t = 525, |
| 197 | S_GTHREAD32_16t = 526, |
| 198 | S_SLINK32 = 527, |
| 199 | S_LPROCMIPS_16t = 768, |
| 200 | S_GPROCMIPS_16t = 769, |
| 201 | S_PROCREF_ST = 1024, |
| 202 | S_DATAREF_ST = 1025, |
| 203 | S_ALIGN = 1026, |
| 204 | S_LPROCREF_ST = 1027, |
| 205 | S_OEM = 1028, |
| 206 | S_TI16_MAX = 4096, |
| 207 | S_REGISTER_ST = 4097, |
| 208 | S_CONSTANT_ST = 4098, |
| 209 | S_UDT_ST = 4099, |
| 210 | S_COBOLUDT_ST = 4100, |
| 211 | S_MANYREG_ST = 4101, |
| 212 | S_BPREL32_ST = 4102, |
| 213 | S_LDATA32_ST = 4103, |
| 214 | S_GDATA32_ST = 4104, |
| 215 | S_PUB32_ST = 4105, |
| 216 | S_LPROC32_ST = 4106, |
| 217 | S_GPROC32_ST = 4107, |
| 218 | S_VFTABLE32 = 4108, |
| 219 | S_REGREL32_ST = 4109, |
| 220 | S_LTHREAD32_ST = 4110, |
| 221 | S_GTHREAD32_ST = 4111, |
| 222 | S_LPROCMIPS_ST = 4112, |
| 223 | S_GPROCMIPS_ST = 4113, |
| 224 | S_COMPILE2_ST = 4115, |
| 225 | S_MANYREG2_ST = 4116, |
| 226 | S_LPROCIA64_ST = 4117, |
| 227 | S_GPROCIA64_ST = 4118, |
| 228 | S_LOCALSLOT_ST = 4119, |
| 229 | S_PARAMSLOT_ST = 4120, |
| 230 | S_ANNOTATION = 4121, |
| 231 | S_GMANPROC_ST = 4122, |
| 232 | S_LMANPROC_ST = 4123, |
| 233 | S_RESERVED1 = 4124, |
| 234 | S_RESERVED2 = 4125, |
| 235 | S_RESERVED3 = 4126, |
| 236 | S_RESERVED4 = 4127, |
| 237 | S_LMANDATA_ST = 4128, |
| 238 | S_GMANDATA_ST = 4129, |
| 239 | S_MANFRAMEREL_ST = 4130, |
| 240 | S_MANREGISTER_ST = 4131, |
| 241 | S_MANSLOT_ST = 4132, |
| 242 | S_MANMANYREG_ST = 4133, |
| 243 | S_MANREGREL_ST = 4134, |
| 244 | S_MANMANYREG2_ST = 4135, |
| 245 | S_MANTYPREF = 4136, |
| 246 | S_UNAMESPACE_ST = 4137, |
| 247 | S_ST_MAX = 4352, |
| 248 | S_WITH32 = 4356, |
| 249 | S_MANYREG = 4362, |
| 250 | S_LPROCMIPS = 4372, |
| 251 | S_GPROCMIPS = 4373, |
| 252 | S_MANYREG2 = 4375, |
| 253 | S_LPROCIA64 = 4376, |
| 254 | S_GPROCIA64 = 4377, |
| 255 | S_LOCALSLOT = 4378, |
| 256 | S_PARAMSLOT = 4379, |
| 257 | S_MANFRAMEREL = 4382, |
| 258 | S_MANREGISTER = 4383, |
| 259 | S_MANSLOT = 4384, |
| 260 | S_MANMANYREG = 4385, |
| 261 | S_MANREGREL = 4386, |
| 262 | S_MANMANYREG2 = 4387, |
| 263 | S_UNAMESPACE = 4388, |
| 264 | S_DATAREF = 4390, |
| 265 | S_ANNOTATIONREF = 4392, |
| 266 | S_TOKENREF = 4393, |
| 267 | S_GMANPROC = 4394, |
| 268 | S_LMANPROC = 4395, |
| 269 | S_ATTR_FRAMEREL = 4398, |
| 270 | S_ATTR_REGISTER = 4399, |
| 271 | S_ATTR_REGREL = 4400, |
| 272 | S_ATTR_MANYREG = 4401, |
| 273 | S_SEPCODE = 4402, |
| 274 | S_LOCAL_2005 = 4403, |
| 275 | S_DEFRANGE_2005 = 4404, |
| 276 | S_DEFRANGE2_2005 = 4405, |
| 277 | S_DISCARDED = 4411, |
| 278 | S_LPROCMIPS_ID = 4424, |
| 279 | S_GPROCMIPS_ID = 4425, |
| 280 | S_LPROCIA64_ID = 4426, |
| 281 | S_GPROCIA64_ID = 4427, |
| 282 | S_DEFRANGE_HLSL = 4432, |
| 283 | S_GDATA_HLSL = 4433, |
| 284 | S_LDATA_HLSL = 4434, |
| 285 | S_LOCAL_DPC_GROUPSHARED = 4436, |
| 286 | S_DEFRANGE_DPC_PTR_TAG = 4439, |
| 287 | S_DPC_SYM_TAG_MAP = 4440, |
| 288 | S_ARMSWITCHTABLE = 4441, |
| 289 | S_POGODATA = 4444, |
| 290 | S_INLINESITE2 = 4445, |
| 291 | S_MOD_TYPEREF = 4447, |
| 292 | S_REF_MINIPDB = 4448, |
| 293 | S_PDBMAP = 4449, |
| 294 | S_GDATA_HLSL32 = 4450, |
| 295 | S_LDATA_HLSL32 = 4451, |
| 296 | S_GDATA_HLSL32_EX = 4452, |
| 297 | S_LDATA_HLSL32_EX = 4453, |
| 298 | S_FASTLINK = 4455, |
| 299 | S_INLINEES = 4456, |
| 300 | S_END = 6, |
| 301 | S_INLINESITE_END = 4430, |
| 302 | S_PROC_ID_END = 4431, |
| 303 | S_THUNK32 = 4354, |
| 304 | S_TRAMPOLINE = 4396, |
| 305 | S_SECTION = 4406, |
| 306 | S_COFFGROUP = 4407, |
| 307 | S_EXPORT = 4408, |
| 308 | S_LPROC32 = 4367, |
| 309 | S_GPROC32 = 4368, |
| 310 | S_LPROC32_ID = 4422, |
| 311 | S_GPROC32_ID = 4423, |
| 312 | S_LPROC32_DPC = 4437, |
| 313 | S_LPROC32_DPC_ID = 4438, |
| 314 | S_REGISTER = 4358, |
| 315 | S_PUB32 = 4366, |
| 316 | S_PROCREF = 4389, |
| 317 | S_LPROCREF = 4391, |
| 318 | S_ENVBLOCK = 4413, |
| 319 | S_INLINESITE = 4429, |
| 320 | S_LOCAL = 4414, |
| 321 | S_DEFRANGE = 4415, |
| 322 | S_DEFRANGE_SUBFIELD = 4416, |
| 323 | S_DEFRANGE_REGISTER = 4417, |
| 324 | S_DEFRANGE_FRAMEPOINTER_REL = 4418, |
| 325 | S_DEFRANGE_SUBFIELD_REGISTER = 4419, |
| 326 | S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE = 4420, |
| 327 | S_DEFRANGE_REGISTER_REL = 4421, |
| 328 | S_BLOCK32 = 4355, |
| 329 | S_LABEL32 = 4357, |
| 330 | S_OBJNAME = 4353, |
| 331 | S_COMPILE2 = 4374, |
| 332 | S_COMPILE3 = 4412, |
| 333 | S_FRAMEPROC = 4114, |
| 334 | S_CALLSITEINFO = 4409, |
| 335 | S_FILESTATIC = 4435, |
| 336 | S_HEAPALLOCSITE = 4446, |
| 337 | S_FRAMECOOKIE = 4410, |
| 338 | S_CALLEES = 4442, |
| 339 | S_CALLERS = 4443, |
| 340 | S_UDT = 4360, |
| 341 | S_COBOLUDT = 4361, |
| 342 | S_BUILDINFO = 4428, |
| 343 | S_BPREL32 = 4363, |
| 344 | S_REGREL32 = 4369, |
| 345 | S_CONSTANT = 4359, |
| 346 | S_MANCONSTANT = 4397, |
| 347 | S_LDATA32 = 4364, |
| 348 | S_GDATA32 = 4365, |
| 349 | S_LMANDATA = 4380, |
| 350 | S_GMANDATA = 4381, |
| 351 | S_LTHREAD32 = 4370, |
| 352 | S_GTHREAD32 = 4371, |
| 353 | }; |
| 354 | |
| 355 | const SectionContrSubstreamVersion = enum(u32) { |
| 356 | Ver60 = 0xeffe0000 + 19970605, |
| 357 | V2 = 0xeffe0000 + 20140516 |
| 358 | }; |
| 359 | |
| 360 | const RecordPrefix = packed struct { |
| 361 | RecordLen: u16, /// Record length, starting from &RecordKind. |
| 362 | RecordKind: u16, /// Record kind enum (SymRecordKind or TypeRecordKind) |
| 363 | }; |
| 364 | |
| 72 | 365 | pub const Pdb = struct { |
| 73 | 366 | in_file: os.File, |
| 74 | 367 | allocator: *mem.Allocator, |
| 368 | coff: *Coff, |
| 75 | 369 | |
| 76 | 370 | msf: Msf, |
| 77 | 371 | |
| 78 | | pub fn openFile(self: *Pdb, allocator: *mem.Allocator, file_name: []u8) !void { |
| 372 | pub fn openFile(self: *Pdb, coff: *Coff, file_name: []u8) !void { |
| 79 | 373 | self.in_file = try os.File.openRead(file_name); |
| 80 | | self.allocator = allocator; |
| 374 | self.allocator = coff.allocator; |
| 375 | self.coff = coff; |
| 81 | 376 | |
| 82 | | try self.msf.openFile(allocator, self.in_file); |
| 377 | try self.msf.openFile(self.allocator, self.in_file); |
| 378 | } |
| 379 | |
| 380 | pub fn getStreamById(self: *Pdb, id: u32) ?*MsfStream { |
| 381 | if (id >= self.msf.streams.len) |
| 382 | return null; |
| 383 | return &self.msf.streams[id]; |
| 83 | 384 | } |
| 84 | 385 | |
| 85 | 386 | pub fn getStream(self: *Pdb, stream: StreamType) ?*MsfStream { |
| 86 | 387 | const id = @enumToInt(stream); |
| 87 | | if (id < self.msf.streams.len) |
| 88 | | return &self.msf.streams[id]; |
| 89 | | return null; |
| 388 | return self.getStreamById(id); |
| 90 | 389 | } |
| 91 | 390 | |
| 92 | 391 | pub fn getSourceLine(self: *Pdb, address: usize) !void { |
| ... | ... | @@ -98,38 +397,106 @@ pub const Pdb = struct { |
| 98 | 397 | std.debug.warn("{}\n", header); |
| 99 | 398 | warn("after header dbi stream at {} (file offset)\n", dbi.getFilePos()); |
| 100 | 399 | |
| 400 | var modules = ArrayList(Module).init(self.allocator); |
| 401 | |
| 101 | 402 | // Module Info Substream |
| 102 | 403 | var mod_info_offset: usize = 0; |
| 103 | | while (mod_info_offset < header.ModInfoSize) { |
| 104 | | const march_forward_bytes = dbi.getFilePos() % 4; |
| 105 | | if (march_forward_bytes != 0) { |
| 106 | | try dbi.seekForward(march_forward_bytes); |
| 107 | | mod_info_offset += march_forward_bytes; |
| 108 | | } |
| 404 | while (mod_info_offset != header.ModInfoSize) { |
| 109 | 405 | var mod_info: ModInfo = undefined; |
| 110 | 406 | try dbi.stream.readStruct(ModInfo, &mod_info); |
| 111 | 407 | std.debug.warn("{}\n", mod_info); |
| 112 | | mod_info_offset += @sizeOf(ModInfo); |
| 408 | var this_record_len: usize = @sizeOf(ModInfo); |
| 113 | 409 | |
| 114 | 410 | const module_name = try dbi.readNullTermString(self.allocator); |
| 115 | 411 | std.debug.warn("module_name '{}'\n", module_name); |
| 116 | | mod_info_offset += module_name.len + 1; |
| 117 | | |
| 118 | | //if (mem.eql(u8, module_name, "piler_rt.obj")) { |
| 119 | | // std.debug.warn("detected bad thing\n"); |
| 120 | | // try dbi.seekTo(dbi.pos - |
| 121 | | // "c:\\msys64\\home\\andy\\zig\\build-llvm6-msvc-release\\.\\zig-cache\\compiler_rt.obj\x00".len - |
| 122 | | // @sizeOf(ModInfo)); |
| 123 | | // mod_info_offset -= module_name.len + 1; |
| 124 | | // continue; |
| 125 | | //} |
| 412 | this_record_len += module_name.len + 1; |
| 126 | 413 | |
| 127 | 414 | const obj_file_name = try dbi.readNullTermString(self.allocator); |
| 128 | 415 | std.debug.warn("obj_file_name '{}'\n", obj_file_name); |
| 129 | | mod_info_offset += obj_file_name.len + 1; |
| 416 | this_record_len += obj_file_name.len + 1; |
| 417 | |
| 418 | const march_forward_bytes = this_record_len % 4; |
| 419 | if (march_forward_bytes != 0) { |
| 420 | try dbi.seekForward(march_forward_bytes); |
| 421 | this_record_len += march_forward_bytes; |
| 422 | } |
| 423 | |
| 424 | try modules.append(Module{ |
| 425 | .mod_info = mod_info, |
| 426 | .module_name = module_name, |
| 427 | .obj_file_name = obj_file_name, |
| 428 | }); |
| 429 | |
| 430 | mod_info_offset += this_record_len; |
| 431 | if (mod_info_offset > header.ModInfoSize) |
| 432 | return error.InvalidDebugInfo; |
| 130 | 433 | } |
| 131 | | std.debug.warn("end modules\n"); |
| 132 | 434 | |
| 435 | // Section Contribution Substream |
| 436 | var sect_contribs = ArrayList(SectionContribEntry).init(self.allocator); |
| 437 | std.debug.warn("looking at Section Contributinos now\n"); |
| 438 | var sect_cont_offset: usize = 0; |
| 439 | if (header.SectionContributionSize != 0) { |
| 440 | const ver = @intToEnum(SectionContrSubstreamVersion, try dbi.stream.readIntLe(u32)); |
| 441 | if (ver != SectionContrSubstreamVersion.Ver60) |
| 442 | return error.InvalidDebugInfo; |
| 443 | sect_cont_offset += @sizeOf(u32); |
| 444 | } |
| 445 | while (sect_cont_offset != header.SectionContributionSize) { |
| 446 | const entry = try sect_contribs.addOne(); |
| 447 | try dbi.stream.readStruct(SectionContribEntry, entry); |
| 448 | std.debug.warn("{}\n", entry); |
| 449 | sect_cont_offset += @sizeOf(SectionContribEntry); |
| 450 | |
| 451 | if (sect_cont_offset > header.SectionContributionSize) |
| 452 | return error.InvalidDebugInfo; |
| 453 | } |
| 454 | //std.debug.warn("looking at section map now\n"); |
| 455 | //if (header.SectionMapSize == 0) |
| 456 | // return error.MissingDebugInfo; |
| 457 | |
| 458 | //var sect_map_hdr: SectionMapHeader = undefined; |
| 459 | //try dbi.stream.readStruct(SectionMapHeader, &sect_map_hdr); |
| 460 | |
| 461 | //const sect_entries = try self.allocator.alloc(SectionMapEntry, sect_map_hdr.Count); |
| 462 | //const as_bytes = @sliceToBytes(sect_entries); |
| 463 | //if (as_bytes.len + @sizeOf(SectionMapHeader) != header.SectionMapSize) |
| 464 | // return error.InvalidDebugInfo; |
| 465 | //try dbi.stream.readNoEof(as_bytes); |
| 466 | |
| 467 | //for (sect_entries) |sect_entry| { |
| 468 | // std.debug.warn("{}\n", sect_entry); |
| 469 | //} |
| 470 | |
| 471 | const mod_index = for (sect_contribs.toSlice()) |sect_contrib| { |
| 472 | const coff_section = self.coff.sections.toSlice()[sect_contrib.Section]; |
| 473 | std.debug.warn("looking in coff name: {}\n", mem.toSliceConst(u8, &coff_section.header.name)); |
| 474 | |
| 475 | const vaddr_start = coff_section.header.virtual_address + sect_contrib.Offset; |
| 476 | const vaddr_end = vaddr_start + sect_contrib.Size; |
| 477 | if (address >= vaddr_start and address < vaddr_end) { |
| 478 | std.debug.warn("found sect contrib: {}\n", sect_contrib); |
| 479 | break sect_contrib.ModuleIndex; |
| 480 | } |
| 481 | } else return error.MissingDebugInfo; |
| 482 | |
| 483 | const mod = &modules.toSlice()[mod_index]; |
| 484 | const modi = self.getStreamById(mod.mod_info.ModuleSymStream) orelse return error.InvalidDebugInfo; |
| 485 | |
| 486 | const signature = try modi.stream.readIntLe(u32); |
| 487 | if (signature != 4) |
| 488 | return error.InvalidDebugInfo; |
| 489 | |
| 490 | const symbols = try self.allocator.alloc(u8, mod.mod_info.SymByteSize - 4); |
| 491 | std.debug.warn("read {} bytes of symbol info\n", symbols.len); |
| 492 | try modi.stream.readNoEof(symbols); |
| 493 | |
| 494 | if (mod.mod_info.C11ByteSize != 0) |
| 495 | return error.InvalidDebugInfo; |
| 496 | |
| 497 | if (mod.mod_info.C13ByteSize != 0) { |
| 498 | std.debug.warn("read C13 line info\n"); |
| 499 | } |
| 133 | 500 | |
| 134 | 501 | // TODO: locate corresponding source line information |
| 135 | 502 | } |