diff options
author | Alan Modra <amodra@gmail.com> | 2023-02-15 07:51:00 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2023-02-15 13:05:28 +1030 |
commit | 72d225ef9cc7d475db188581da33b056df3191fd (patch) | |
tree | 033d54528bb39c234342c7527648f9f30a1d211c /binutils/stabs.c | |
parent | 3cd0b4f2c03ddfce91343dd8409407aab3ebb47d (diff) | |
download | gdb-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.c | 36 |
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; |