diff options
author | Eugene Tarassov | 2022-07-26 21:16:00 +0000 |
---|---|---|
committer | Eugene Tarassov | 2022-07-26 23:46:20 +0000 |
commit | 137abb25dd1f753fcfff35ef52a33644cb456ce0 (patch) | |
tree | e4e2c9e3fd63646c4bfd00cdcd619ea5e89428e9 | |
parent | 2589d4a159e8e6818f6dd7beb122ab5f08c04fbc (diff) | |
download | org.eclipse.tcf.agent-137abb25dd1f753fcfff35ef52a33644cb456ce0.tar.gz org.eclipse.tcf.agent-137abb25dd1f753fcfff35ef52a33644cb456ce0.tar.xz org.eclipse.tcf.agent-137abb25dd1f753fcfff35ef52a33644cb456ce0.zip |
Bug 580450 - failed to read the full compilation unit tag in dwarf 5 when customized sections
-rw-r--r-- | agent/tcf/services/dwarf.h | 2 | ||||
-rw-r--r-- | agent/tcf/services/dwarfcache.c | 27 | ||||
-rw-r--r-- | agent/tcf/services/dwarfcache.h | 35 | ||||
-rw-r--r-- | agent/tcf/services/dwarfio.c | 140 | ||||
-rw-r--r-- | agent/tcf/services/dwarfio.h | 9 |
5 files changed, 96 insertions, 117 deletions
diff --git a/agent/tcf/services/dwarf.h b/agent/tcf/services/dwarf.h index 2c831def..6ab31286 100644 --- a/agent/tcf/services/dwarf.h +++ b/agent/tcf/services/dwarf.h @@ -302,6 +302,8 @@ #define AT_GNAT_descriptive_type 0x2302 #define AT_hi_user_v2 0x3fff +/* Pseudo-attribute, used to indicate first pass over comp unit info */ +#define AT_read_base_offsets 0xffff #define OP_reg 0x01 /* v1 */ #define OP_basereg 0x02 /* v1 */ diff --git a/agent/tcf/services/dwarfcache.c b/agent/tcf/services/dwarfcache.c index af010c72..4e297ab9 100644 --- a/agent/tcf/services/dwarfcache.c +++ b/agent/tcf/services/dwarfcache.c @@ -790,7 +790,12 @@ static void read_object_info(U2_T Tag, U2_T Attr, U2_T Form) { break; case AT_ranges: if (Tag == TAG_base_type || Tag == TAG_fund_type || Tag == TAG_index_range) break; - dio_ChkData(Form); + if (Form == FORM_RNGLISTX) { + Info->mFlags |= DOIF_range_list; + } + else { + dio_ChkData(Form); + } Info->u.mCode.mHighPC.mRanges = dio_gFormData; Info->mFlags |= DOIF_ranges; break; @@ -857,6 +862,7 @@ static void read_object_info(U2_T Tag, U2_T Attr, U2_T Form) { case FORM_DATA8: case FORM_DATA16: case FORM_SEC_OFFSET: + case FORM_LOCLISTX: Info->mFlags |= DOIF_need_frame; break; } @@ -928,12 +934,6 @@ static void read_object_info(U2_T Tag, U2_T Attr, U2_T Form) { dio_ChkData(Form); Unit->mLanguage = (U2_T)dio_gFormData; break; - case AT_loclists_base: - dio_ReadSectionPointer(Form, &Unit->mLocListsSection, &Unit->mLocListsOffs, sCache->mDebugLocLists); - break; - case AT_rnglists_base: - dio_ReadSectionPointer(Form, &Unit->mRngListsSection, &Unit->mRngListsOffs, sCache->mDebugRngLists); - break; } } } @@ -1084,11 +1084,14 @@ void start_dwarf_addr_ranges(ObjectInfo * Obj, ObjectAddressRange * Range) { Range->mRngSection = Cache->mDebugRanges; } } - else { - if (Cache->mDebugRngLists) { - dio_EnterSection(&Range->mUnit->mDesc, Cache->mDebugRngLists, Obj->u.mCode.mHighPC.mRanges); - Range->mRngSection = Cache->mDebugRngLists; - } + else if (Obj->mFlags & DOIF_range_list) { + if (Range->mUnit->mDesc.mRngListsSection == NULL) str_exception(ERR_INV_DWARF, "Missing AT_rnglists_base"); + dio_EnterSection(&Range->mUnit->mDesc, Range->mUnit->mDesc.mRngListsSection, Range->mUnit->mDesc.mRngListsOffs + Obj->u.mCode.mHighPC.mRanges); + Range->mRngSection = Range->mUnit->mDesc.mRngListsSection; + } + else if (Cache->mDebugRngLists) { + dio_EnterSection(&Range->mUnit->mDesc, Cache->mDebugRngLists, Obj->u.mCode.mHighPC.mRanges); + Range->mRngSection = Cache->mDebugRngLists; } Range->mDone = Range->mRngSection == NULL; } diff --git a/agent/tcf/services/dwarfcache.h b/agent/tcf/services/dwarfcache.h index 022d5f7f..6e512176 100644 --- a/agent/tcf/services/dwarfcache.h +++ b/agent/tcf/services/dwarfcache.h @@ -83,20 +83,21 @@ struct FileInfo { #define DOIF_children_loaded 0x0000200 #define DOIF_ranges 0x0000400 #define DOIF_aranges 0x0000800 -#define DOIF_find_mark 0x0001000 -#define DOIF_load_mark 0x0002000 -#define DOIF_pub_mark 0x0004000 -#define DOIF_low_pc 0x0008000 -#define DOIF_need_frame 0x0010000 -#define DOIF_mips_linkage_name 0x0020000 -#define DOIF_linkage_name 0x0040000 -#define DOIF_mangled_name 0x0080000 -#define DOIF_optional 0x0100000 -#define DOIF_location 0x0200000 -#define DOIF_data_location 0x0400000 -#define DOIF_const_value 0x0800000 -#define DOIF_inv_reference 0x1000000 -#define DOIF_inlined 0x2000000 +#define DOIF_range_list 0x0001000 +#define DOIF_find_mark 0x0002000 +#define DOIF_load_mark 0x0004000 +#define DOIF_pub_mark 0x0008000 +#define DOIF_low_pc 0x0010000 +#define DOIF_need_frame 0x0020000 +#define DOIF_mips_linkage_name 0x0040000 +#define DOIF_linkage_name 0x0080000 +#define DOIF_mangled_name 0x0100000 +#define DOIF_optional 0x0200000 +#define DOIF_location 0x0400000 +#define DOIF_data_location 0x0800000 +#define DOIF_const_value 0x1000000 +#define DOIF_inv_reference 0x2000000 +#define DOIF_inlined 0x4000000 struct ObjectInfo { @@ -230,12 +231,6 @@ struct CompUnit { CompUnit * mNextTypeUnit; ContextAddress mFundTypeID; - - ELF_Section * mLocListsSection; - U8_T mLocListsOffs; - - ELF_Section * mRngListsSection; - U8_T mRngListsOffs; }; /* Address range of a compilation unit. A unit can occupy multiple address ranges. */ diff --git a/agent/tcf/services/dwarfio.c b/agent/tcf/services/dwarfio.c index c00a48f0..70523115 100644 --- a/agent/tcf/services/dwarfio.c +++ b/agent/tcf/services/dwarfio.c @@ -361,6 +361,27 @@ void dio_ReadSectionPointer(U2_T Form, ELF_Section ** Section, U8_T * Offs, ELF_ } } +static void dio_FindSection(ELF_File * File, const char * Name, ELF_Section ** Res) { + ELF_Section * Section = NULL; + U4_T ID; + + for (ID = 1; ID < File->section_cnt; ID++) { + if (strcmp(File->sections[ID].name, Name) == 0) { + if (Section != NULL) { + str_exception(ERR_INV_DWARF, "More than one .debug_str section in a file"); + } + Section = File->sections + ID; + assert(Section->file == File); + } + } + + if (Section == NULL) { + str_fmt_exception(ERR_INV_DWARF, "Section %s not found", Name); + } + + *Res = Section; +} + static U1_T * dio_LoadStringTable(ELF_File * File, ELF_Section * Section, U8_T * StringTableAddr, U4_T * StringTableSize) { DIO_Cache * Cache = dio_GetCache(File); @@ -372,21 +393,7 @@ static U1_T * dio_LoadStringTable(ELF_File * File, ELF_Section * Section, U8_T * } if (Cache->mStringTable == NULL) { - U4_T ID; - - for (ID = 1; ID < File->section_cnt; ID++) { - if (strcmp(File->sections[ID].name, ".debug_str") == 0) { - if (Section != NULL) { - str_exception(ERR_INV_DWARF, "More than one .debug_str section in a file"); - } - Section = File->sections + ID; - assert(Section->file == File); - } - } - - if (Section == NULL) { - str_exception(ERR_INV_DWARF, "Section .debug_str not found"); - } + dio_FindSection(File, ".debug_str", &Section); if (elf_load(Section) < 0) { str_exception(errno, "Cannot read .debug_str section"); @@ -413,22 +420,9 @@ static U1_T * dio_LoadLineStringTable(ELF_File * File, ELF_Section * Section, U8 } if (Cache->mLineStringTable == NULL) { - U4_T ID; ELF_Section * Section = NULL; - for (ID = 1; ID < File->section_cnt; ID++) { - if (strcmp(File->sections[ID].name, ".debug_line_str") == 0) { - if (Section != NULL) { - str_exception(ERR_INV_DWARF, "More than one .debug_line_str section in a file"); - } - Section = File->sections + ID; - assert(Section->file == File); - } - } - - if (Section == NULL) { - str_exception(ERR_INV_DWARF, "Section .debug_line_str not found"); - } + dio_FindSection(File, ".debug_line_str", &Section); if (elf_load(Section) < 0) { str_exception(errno, "Cannot read .debug_line_str section"); @@ -723,6 +717,18 @@ int dio_ReadEntry(DIO_EntryCallBack CallBack, U2_T TargetAttr) { case AT_extension: break; default: + if (TargetAttr == AT_read_base_offsets) { + int ok = 0; + switch (Attr) { + case AT_addr_base: + case AT_str_offsets_base: + case AT_rnglists_base: + case AT_loclists_base: + ok = 1; + break; + } + if (ok) break; + } switch (Form) { case FORM_ADDR : sDataPos += sAddressSize; continue; case FORM_REF : sDataPos += 4; continue; @@ -808,21 +814,7 @@ static void dio_LoadAbbrevTable(DIO_UnitDescriptor * Unit) { U4_T AbbrevBufPos = 0; if (Cache->mAbbrevSection == NULL) { - ELF_Section * Section = NULL; - unsigned i; - - for (i = 1; i < File->section_cnt; i++) { - if (strcmp(File->sections[i].name, ".debug_abbrev") == 0) { - if (Section != NULL) { - str_exception(ERR_INV_DWARF, "More than one .debug_abbrev section in a file"); - } - Section = File->sections + i; - } - } - if (Section == NULL) { - str_exception(ERR_INV_DWARF, "Missing .debug_abbrev section"); - } - Cache->mAbbrevSection = Section; + dio_FindSection(File, ".debug_abbrev", &Cache->mAbbrevSection); } dio_EnterSection(Unit, Cache->mAbbrevSection, Unit->mAbbrevTableAddr - Cache->mAbbrevSection->addr); @@ -893,48 +885,28 @@ static void dio_LoadAbbrevTable(DIO_UnitDescriptor * Unit) { dio_ExitSection(); } -static void dio_ReadUnitStrOffsetsBase(U2_T Tag, U2_T Attr, U2_T Form) { - U4_T ID; +static void dio_ReadUnitBaseOffsets(U2_T Tag, U2_T Attr, U2_T Form) { ELF_Section * Section = NULL; ELF_File * File = sSection->file; - for (ID = 1; ID < File->section_cnt; ID++) { - if (strcmp(File->sections[ID].name, ".debug_str_offsets") == 0) { - if (Section != NULL) { - str_exception(ERR_INV_DWARF, "More than one .debug_str_offsets section in a file"); - } - Section = File->sections + ID; - assert(Section->file == File); - } - } - - if (Section == NULL) { - str_exception(ERR_INV_DWARF, "Section .debug_str_offsets not found"); - } - - dio_ReadSectionPointer(Form, &sUnit->mStrOffsetsSection, &sUnit->mStrOffsetsOffs, Section); -} - -static void dio_ReadUnitAddrBase(U2_T Tag, U2_T Attr, U2_T Form) { - U4_T ID; - ELF_Section * Section = NULL; - ELF_File * File = sSection->file; - - for (ID = 1; ID < File->section_cnt; ID++) { - if (strcmp(File->sections[ID].name, ".debug_addr") == 0) { - if (Section != NULL) { - str_exception(ERR_INV_DWARF, "More than one .debug_addr section in a file"); - } - Section = File->sections + ID; - assert(Section->file == File); - } - } - - if (Section == NULL) { - str_exception(ERR_INV_DWARF, "Section .debug_addr not found"); + switch (Attr) { + case AT_addr_base: + dio_FindSection(File, ".debug_addr", &Section); + dio_ReadSectionPointer(Form, &sUnit->mAddrInfoSection, &sUnit->mAddrInfoOffs, Section); + break; + case AT_str_offsets_base: + dio_FindSection(File, ".debug_str_offsets", &Section); + dio_ReadSectionPointer(Form, &sUnit->mStrOffsetsSection, &sUnit->mStrOffsetsOffs, Section); + break; + case AT_rnglists_base: + dio_FindSection(File, ".debug_rnglists", &Section); + dio_ReadSectionPointer(Form, &sUnit->mRngListsSection, &sUnit->mRngListsOffs, Section); + break; + case AT_loclists_base: + dio_FindSection(File, ".debug_loclists", &Section); + dio_ReadSectionPointer(Form, &sUnit->mLocListsSection, &sUnit->mLocListsOffs, Section); + break; } - - dio_ReadSectionPointer(Form, &sUnit->mAddrInfoSection, &sUnit->mAddrInfoOffs, Section); } void dio_ReadUnit(DIO_UnitDescriptor * Unit, DIO_EntryCallBack CallBack) { @@ -995,9 +967,7 @@ void dio_ReadUnit(DIO_UnitDescriptor * Unit, DIO_EntryCallBack CallBack) { sSectionRefSize = sUnit->m64bit ? 8 : 4; if (sUnit->mVersion >= 5) { U8_T DataPos = sDataPos; - dio_ReadEntry(dio_ReadUnitAddrBase, AT_addr_base); - sDataPos = DataPos; - dio_ReadEntry(dio_ReadUnitStrOffsetsBase, AT_str_offsets_base); + dio_ReadEntry(dio_ReadUnitBaseOffsets, AT_read_base_offsets); sDataPos = DataPos; } while (sUnit->mUnitSize == 0 || sDataPos < sUnit->mUnitOffs + sUnit->mUnitSize) { diff --git a/agent/tcf/services/dwarfio.h b/agent/tcf/services/dwarfio.h index 547c6c94..1fa4342c 100644 --- a/agent/tcf/services/dwarfio.h +++ b/agent/tcf/services/dwarfio.h @@ -39,12 +39,21 @@ typedef struct DIO_UnitDescriptor { U8_T mCompUnitID; U8_T mTypeSignature; U8_T mTypeOffset; + struct DIO_Abbreviation ** mAbbrevTable; U4_T mAbbrevTableSize; + ELF_Section * mStrOffsetsSection; U8_T mStrOffsetsOffs; + ELF_Section * mAddrInfoSection; U8_T mAddrInfoOffs; + + ELF_Section * mLocListsSection; + U8_T mLocListsOffs; + + ELF_Section * mRngListsSection; + U8_T mRngListsOffs; } DIO_UnitDescriptor; extern U8_T dio_gEntryPos; |