[PATCH v2][makedumpfile 05/14] eppic dwarf: support anonymous structs member resolving
Tao Liu
ltao at redhat.com
Mon Oct 20 15:24:01 PDT 2025
Previously, apimember cannot dive into members which belongs to anonymous
structs. E.g. mm_struct has structure as follows:
0x000027bc: DW_TAG_structure_type
DW_AT_name ("mm_struct")
0x000027cb: DW_TAG_member
DW_AT_type (0x00008dde "structure ")
0x000027d2: DW_TAG_member
DW_AT_name ("cpu_bitmap")
0x00008dde: DW_TAG_structure_type
0x00008deb: DW_TAG_member
DW_AT_type (0x00008d8e "structure ")
0x00008df2: DW_TAG_member
DW_AT_name ("mm_mt")
0x00008e00: DW_TAG_member
DW_AT_name ("mmap_base")
0x00008e0e: DW_TAG_member
DW_AT_name ("mmap_legacy_base")
GET_DIE_NFIELDS_ALL() for mm_struct will only iterate 2 members, it will
not dive into the anonymous structure and iterate members as mm_mt,
mmap_base etc. In other words, there is no way to reference members as
mm_struct.mm_mt.
This patch will make apimember recursive, when anonymous struct/union found,
it will dive deeper to discover further members to make mm_struct.mm_mt
reference possible.
E.g for the following eppic program:
int main()
{
struct mm_struct *m = (struct mm_struct *)0xffff96b7d1afa680;
printf("%lx\n", &m->mm_mt);
return 0;
}
Before the patch:
File /tmp/test.c, line 4, Error: Unknown member name [mm_mt]
After the patch:
ffff96b7d1afa6c0
---
extension_eppic.c | 73 ++++++++++++++++++++++++++++++-----------------
1 file changed, 47 insertions(+), 26 deletions(-)
diff --git a/extension_eppic.c b/extension_eppic.c
index c4a13b9..ebace25 100644
--- a/extension_eppic.c
+++ b/extension_eppic.c
@@ -223,13 +223,16 @@ out:
* Get the type, size and position information for a member of a structure.
*/
static char *
-apimember(char *mname, ull idx, type_t *tm, member_t *m, ull *last_index)
+apimember_internal(char *mname, ull idx, type_t *tm, member_t *m,
+ long offset_base, ull *target_index, ull *global_index)
{
- int index, nfields = -1, size;
+ int index = 0, nfields = -1, size;
int nbits = 0, fbits = 0;
long offset;
unsigned long long m_die, die_off = idx;
- char *name = NULL;
+ int type_flag;
+ unsigned long long t_die_off;
+ char *name;
nfields = GET_DIE_NFIELDS_ALL(die_off);
/*
@@ -239,43 +242,61 @@ apimember(char *mname, ull idx, type_t *tm, member_t *m, ull *last_index)
if (nfields <= 0)
return NULL;
- /* if we're being asked the next member in a getfirst/getnext
- * sequence
- */
- if (mname && !mname[0] && last_index && (*last_index))
- index = *last_index;
- else
- index = 0;
-
while (index < nfields) {
+ name = NULL;
size = GET_DIE_MEMBER_ALL(die_off, index, &offset, &name,
&nbits, &fbits, &m_die);
if (size < 0)
return NULL;
- if (!mname || !mname[0] || !strcmp(mname, name)) {
- eppic_member_ssize(m, size);
- if (name) {
- eppic_member_sname(m, name);
- /*
- * Free the memory allocated by makedumpfile.
- */
- free(name);
+ if (!name && GET_DIE_ATTR_TYPE(m_die, &type_flag, &t_die_off)) {
+ char *ret;
+ ret = apimember_internal(mname, t_die_off, tm, m,
+ offset_base + offset, target_index, global_index);
+ if (ret)
+ return ret;
+ else {
+ index++;
+ continue;
}
- else
- eppic_member_sname(m, "");
- eppic_member_soffset(m, offset);
- eppic_member_snbits(m, nbits);
- eppic_member_sfbit(m, fbits);
- *last_index = index + 1;
- return drilldown(m_die, tm);
+ }
+
+ if (*target_index == *global_index) {
+ if (!mname || !mname[0] || !strcmp(mname, name)) {
+ eppic_member_ssize(m, size);
+ if (name) {
+ eppic_member_sname(m, name);
+ /*
+ * Free the memory allocated by makedumpfile.
+ */
+ free(name);
+ }
+ else
+ eppic_member_sname(m, "");
+ eppic_member_soffset(m, offset + offset_base);
+ eppic_member_snbits(m, nbits);
+ eppic_member_sfbit(m, fbits);
+ return drilldown(m_die, tm);
+ } else
+ return eppic_strdup("");
}
index++;
+ (*global_index)++;
}
return NULL;
}
+static char *
+apimember(char *mname, ull idx, type_t *tm, member_t *m, ull *target_index)
+{
+ char *ret;
+ ull global_index = 0;
+ ret = apimember_internal(mname, idx, tm, m, 0, target_index, &global_index);
+ (*target_index)++;
+ return ret;
+}
+
static int
apigetctype(int ctype, char *name, type_t *tout)
{
--
2.47.0
More information about the kexec
mailing list