Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEugene Tarassov2022-07-26 21:16:00 +0000
committerEugene Tarassov2022-07-26 23:46:20 +0000
commit137abb25dd1f753fcfff35ef52a33644cb456ce0 (patch)
treee4e2c9e3fd63646c4bfd00cdcd619ea5e89428e9
parent2589d4a159e8e6818f6dd7beb122ab5f08c04fbc (diff)
downloadorg.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.h2
-rw-r--r--agent/tcf/services/dwarfcache.c27
-rw-r--r--agent/tcf/services/dwarfcache.h35
-rw-r--r--agent/tcf/services/dwarfio.c140
-rw-r--r--agent/tcf/services/dwarfio.h9
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;

Back to the top