as the bug report shows we had an overflow in the test if
hash table resizing is needed. Reorder the expression to avoid
that. There's still a bug somewhere in gracefully handling
failure in resizing (e.g. out of memory), but this pushes the
boundary for that occurring somewhen into the future and
immediately helps the reporter.
bfd/
PR ld/31009
* merge.c (NEEDS_RESIZE): New macro avoiding overflow.
(sec_merge_maybe_resize): Use it.
(sec_merge_hash_insert): Ditto.
struct sec_merge_hash_entry **values;
};
struct sec_merge_hash_entry **values;
};
+/* True when given NEWCOUNT and NBUCKETS indicate that the hash table needs
+ resizing. */
+#define NEEDS_RESIZE(newcount, nbuckets) ((newcount) > (nbuckets) / 3 * 2)
+
struct sec_merge_sec_info;
/* Information per merged blob. This is the unit of merging and is
struct sec_merge_sec_info;
/* Information per merged blob. This is the unit of merging and is
sec_merge_maybe_resize (struct sec_merge_hash *table, unsigned added)
{
struct bfd_hash_table *bfdtab = &table->table;
sec_merge_maybe_resize (struct sec_merge_hash *table, unsigned added)
{
struct bfd_hash_table *bfdtab = &table->table;
- if (bfdtab->count + added > table->nbuckets * 2 / 3)
+ if (NEEDS_RESIZE (bfdtab->count + added, table->nbuckets))
{
unsigned i;
unsigned long newnb = table->nbuckets * 2;
{
unsigned i;
unsigned long newnb = table->nbuckets * 2;
uint64_t *newl;
unsigned long alloc;
uint64_t *newl;
unsigned long alloc;
- while (bfdtab->count + added > newnb * 2 / 3)
+ while (NEEDS_RESIZE (bfdtab->count + added, newnb))
{
newnb *= 2;
if (!newnb)
{
newnb *= 2;
if (!newnb)
hashp->alignment = 0;
hashp->u.suffix = NULL;
hashp->next = NULL;
hashp->alignment = 0;
hashp->u.suffix = NULL;
hashp->next = NULL;
- // We must not need resizing, otherwise _index is wrong
- BFD_ASSERT (bfdtab->count + 1 <= table->nbuckets * 2 / 3);
+ // We must not need resizing, otherwise the estimation was wrong
+ BFD_ASSERT (!NEEDS_RESIZE (bfdtab->count + 1, table->nbuckets));
bfdtab->count++;
table->key_lens[_index] = (hash << 32) | (uint32_t)len;
table->values[_index] = hashp;
bfdtab->count++;
table->key_lens[_index] = (hash << 32) | (uint32_t)len;
table->values[_index] = hashp;