bfd: use less memory in string merging
authorMichael Matz <matz@suse.de>
Tue, 7 Nov 2023 16:12:46 +0000 (17:12 +0100)
committerMichael Matz <matz@suse.de>
Thu, 9 Nov 2023 16:42:48 +0000 (17:42 +0100)
the offset-to-entry mappings are allocated in blocks, which may
become a bit wasteful in case there are extremely many small
input files or sections.  This made it so that a large project
(Qt5WebEngine) didn't build anymore on x86 32bit due to address
space limits.  It barely fit into address space before the new
string merging, and then got pushed over the limit by this.

So instead of leaving the waste reallocate the maps to their final
size once known.  Now the link barely fits again.

bfd/
    * merge.c (record_section): Reallocate offset maps to their
    final size.

bfd/merge.c

index 61ffab4d706c0e063097877e2578172a309e228d..eeaa1a01fe3868549a8d34a7625208db5cc4ae5c 100644 (file)
@@ -711,6 +711,7 @@ record_section (struct sec_merge_info *sinfo,
   unsigned int align;
   bfd_size_type amt;
   bfd_byte *contents;
+  void *tmpptr;
 
   amt = sec->size;
   if (sec->flags & SEC_STRINGS)
@@ -771,6 +772,19 @@ record_section (struct sec_merge_info *sinfo,
 
   free (contents);
   contents = NULL;
+
+  /* We allocate the ofsmap arrays in blocks of 2048 elements.
+     In case we have very many small input files/sections,
+     this might waste large amounts of memory, so reallocate these
+     arrays here to their true size.  */
+  amt = secinfo->noffsetmap + 1;
+  tmpptr = bfd_realloc (secinfo->map, amt * sizeof(secinfo->map[0]));
+  if (tmpptr)
+    secinfo->map = tmpptr;
+  tmpptr = bfd_realloc (secinfo->map_ofs, amt * sizeof(secinfo->map_ofs[0]));
+  if (tmpptr)
+    secinfo->map_ofs = tmpptr;
+
   /*printf ("ZZZ %s:%s %u entries\n", sec->owner->filename, sec->name,
          (unsigned)secinfo->noffsetmap);*/