summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libdw/ChangeLog5
-rw-r--r--libdw/dwarf_getmacros.c30
2 files changed, 31 insertions, 4 deletions
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 3abb3828..87c7d821 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,8 @@
+2015-04-21 Mark Wielaard <[email protected]>
+
+ * dwarf_getmacros.c (read_macros): Allocate attributes dynamically
+ when there are more than 8.
+
2015-04-01 Petr Machata <[email protected]>
* libdwP.h (DWARF_E_NOT_CUDIE): New enumerator.
diff --git a/libdw/dwarf_getmacros.c b/libdw/dwarf_getmacros.c
index f9f29961..740368ef 100644
--- a/libdw/dwarf_getmacros.c
+++ b/libdw/dwarf_getmacros.c
@@ -361,7 +361,22 @@ read_macros (Dwarf *dbg, int sec_index,
.endp = (void *) endp,
};
- Dwarf_Attribute attributes[proto->nforms];
+ Dwarf_Attribute *attributes;
+ Dwarf_Attribute *attributesp = NULL;
+ Dwarf_Attribute nattributes[8];
+ if (unlikely (proto->nforms > 8))
+ {
+ attributesp = malloc (sizeof (Dwarf_Attribute) * proto->nforms);
+ if (attributesp == NULL)
+ {
+ __libdw_seterrno (DWARF_E_NOMEM);
+ return -1;
+ }
+ attributes = attributesp;
+ }
+ else
+ attributes = &nattributes[0];
+
for (Dwarf_Word i = 0; i < proto->nforms; ++i)
{
/* We pretend this is a DW_AT_GNU_macros attribute so that
@@ -373,8 +388,11 @@ read_macros (Dwarf *dbg, int sec_index,
attributes[i].cu = &fake_cu;
size_t len = __libdw_form_val_len (&fake_cu, proto->forms[i], readp);
- if (len == (size_t) -1)
- return -1;
+ if (unlikely (len == (size_t) -1))
+ {
+ free (attributesp);
+ return -1;
+ }
readp += len;
}
@@ -385,7 +403,11 @@ read_macros (Dwarf *dbg, int sec_index,
.attributes = attributes,
};
- if (callback (&macro, arg) != DWARF_CB_OK)
+ int res = callback (&macro, arg);
+ if (unlikely (attributesp != NULL))
+ free (attributesp);
+
+ if (res != DWARF_CB_OK)
return readp - startp;
}