1$: DW_TAG_unspecified_type DW_AT_name("void") ... 2$ DW_TAG_base_type DW_AT_name("int") ... 3$: DW_TAG_class_type DW_AT_name("A") ... 4$: DW_TAG_pointer_type DW_AT_type(reference to 3$) ... 5$: DW_TAG_const_type DW_AT_type(reference to 3$) ... 6$: DW_TAG_pointer_type DW_AT_type(reference to 5$) ... 7$: DW_TAG_subprogram DW_AT_name("func1") DW_AT_type(reference to 1$) DW_AT_object_pointer(reference to 8$) ! References a formal parameter in this member function ... 8$: DW_TAG_formal_parameter DW_AT_artificial(true) DW_AT_name("this") DW_AT_type(reference to 4$) ! Makes type of 'this' as 'A*' => ! func1 has not been marked constorvolatile DW_AT_location ... ... 9$: DW_TAG_formal_parameter DW_AT_name(x1) DW_AT_type(reference to 2$) ... 10$: DW_TAG_subprogram DW_AT_name("func2") DW_AT_type(reference to 1$) DW_AT_object_pointer(reference to 11$) ! References a formal parameter in this member function ... 11$: DW_TAG_formal_parameter DW_AT_artificial(true) DW_AT_name("this") DW_AT_type(reference to 6$) ! Makes type of 'this' as 'A const*' => ! func2 marked as const DW_AT_location ... ... 12$: DW_TAG_subprogram DW_AT_name("func3") DW_AT_type(reference to 1$) ... ! No 'this' formal parameter => func3 is static 13$: DW_TAG_formal_parameter DW_AT_name(x3) DW_AT_type(reference to 2$) ...
! Concrete instance for call "OUTER(7)" ! OUTER.CI.1.1: DW_TAG_inlined_subroutine ! No name DW_AT_abstract_origin(reference to OUTER.AI.1.1) DW_AT_low_pc(...) DW_AT_high_pc(...) OUTER.CI.1.2: DW_TAG_formal_parameter ! No name DW_AT_abstract_origin(reference to OUTER.AI.1.2) DW_AT_const_value(7) OUTER.CI.1.3: DW_TAG_variable ! No name DW_AT_abstract_origin(reference to OUTER.AI.1.3) DW_AT_location(...) ! ! No DW_TAG_subprogram(abstract instance)for INNER ! ! Concrete instance for call INNER(OUTER_LOCAL) ! INNER.CI.1.1: DW_TAG_inlined_subroutine ! No name DW_AT_abstract_origin(reference to INNER.AI.1.1) DW_AT_low_pc(...) DW_AT_high_pc(...) DW_AT_static_link(...) INNER.CI.1.2: DW_TAG_formal_parameter ! No name DW_AT_abstract_origin(reference to INNER.AI.1.2) DW_AT_location(...) INNER.CI.1.3: DW_TAG_variable ! No name DW_AT_abstract_origin(reference to INNER.AI.1.3) DW_AT_location(...) ... 0
! Another concrete instance of INNER within OUTER ! for the call "INNER(31)"
... 0
非定义调试信息项处理
当函数定义并不在声明区域时,subprogram DIE 就会有 DW_AT_specification 属性,指向相关的函数定义DIE. 对于带有 DW_AT_specification 的调试信息项,我们需要进行特殊处理。
// Get indirect symbol table (array of uint32_t indices into symbol table) uint32_t *indirect_symtab = (uint32_t *)(linkedit_base + dysymtab_cmd->indirectsymoff);
cur = (uintptr_t)header + sizeof(mach_header_t); for (uint i = 0; i < header->ncmds; i++, cur += cur_seg_cmd->cmdsize) { cur_seg_cmd = (segment_command_t *)cur; if (cur_seg_cmd->cmd == LC_SEGMENT_ARCH_DEPENDENT) { if (strcmp(cur_seg_cmd->segname, SEG_DATA) != 0 && strcmp(cur_seg_cmd->segname, SEG_DATA_CONST) != 0) { continue; } for (uint j = 0; j < cur_seg_cmd->nsects; j++) { section_t *sect = (section_t *)(cur + sizeof(segment_command_t)) + j; if ((sect->flags & SECTION_TYPE) == S_LAZY_SYMBOL_POINTERS) { perform_rebinding_with_section(rebindings, sect, slide, symtab, strtab, indirect_symtab); } if ((sect->flags & SECTION_TYPE) == S_NON_LAZY_SYMBOL_POINTERS) { perform_rebinding_with_section(rebindings, sect, slide, symtab, strtab, indirect_symtab); } } } } }