aboutsummaryrefslogtreecommitdiff
path: root/binutils/stabs.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2023-02-15 07:51:00 +1030
committerAlan Modra <amodra@gmail.com>2023-02-15 13:05:28 +1030
commit72d225ef9cc7d475db188581da33b056df3191fd (patch)
tree033d54528bb39c234342c7527648f9f30a1d211c /binutils/stabs.c
parent3cd0b4f2c03ddfce91343dd8409407aab3ebb47d (diff)
downloadgdb-72d225ef9cc7d475db188581da33b056df3191fd.zip
gdb-72d225ef9cc7d475db188581da33b056df3191fd.tar.gz
gdb-72d225ef9cc7d475db188581da33b056df3191fd.tar.bz2
binutils stabs type list
Fuzzers have found that specifying a large stab type number results in lots of memory being requested, as the list is extended with a 16 element array at a time until we reach the given stab type. It also takes a long time. Of course normal sane stab types use small positive integers, but it's not hard to modify the code to handle type numbers starting anyhere. * stabs.c (struct stab_types): Add base_index. (stab_find_slot): Simplify filenum check. Delete type number check. Don't allocate entire array from 0 to type number, allocate a sparse array.
Diffstat (limited to 'binutils/stabs.c')
-rw-r--r--binutils/stabs.c36
1 files changed, 15 insertions, 21 deletions
diff --git a/binutils/stabs.c b/binutils/stabs.c
index 5b0249b..85eebeb 100644
--- a/binutils/stabs.c
+++ b/binutils/stabs.c
@@ -121,6 +121,8 @@ struct stab_types
{
/* Next set of slots for this file. */
struct stab_types *next;
+ /* Where the TYPES array starts. */
+ unsigned int base_index;
/* Types indexed by type number. */
#define STAB_TYPES_SLOTS (16)
debug_type types[STAB_TYPES_SLOTS];
@@ -3413,40 +3415,32 @@ stab_emit_pending_vars (void *dhandle, struct stab_handle *info)
static debug_type *
stab_find_slot (struct stab_handle *info, const int *typenums)
{
- int filenum;
- int tindex;
+ unsigned int filenum;
+ unsigned int tindex;
+ unsigned int base_index;
struct stab_types **ps;
filenum = typenums[0];
tindex = typenums[1];
- if (filenum < 0 || (unsigned int) filenum >= info->files)
+ if (filenum >= info->files)
{
fprintf (stderr, _("Type file number %d out of range\n"), filenum);
return NULL;
}
- if (tindex < 0)
- {
- fprintf (stderr, _("Type index number %d out of range\n"), tindex);
- return NULL;
- }
ps = info->file_types + filenum;
+ base_index = tindex / STAB_TYPES_SLOTS * STAB_TYPES_SLOTS;
+ tindex -= base_index;
+ while (*ps && (*ps)->base_index < base_index)
+ ps = &(*ps)->next;
- while (tindex >= STAB_TYPES_SLOTS)
- {
- if (*ps == NULL)
- {
- *ps = (struct stab_types *) xmalloc (sizeof **ps);
- memset (*ps, 0, sizeof **ps);
- }
- ps = &(*ps)->next;
- tindex -= STAB_TYPES_SLOTS;
- }
- if (*ps == NULL)
+ if (*ps == NULL || (*ps)->base_index != base_index)
{
- *ps = (struct stab_types *) xmalloc (sizeof **ps);
- memset (*ps, 0, sizeof **ps);
+ struct stab_types *n = xcalloc (1, sizeof (*n));
+ n->next = *ps;
+ n->base_index = base_index;
+ *ps = n;
}
return (*ps)->types + tindex;