[binutils-gdb] Tidy .eh_frame rawsize manipulation

Alan Modra amodra@sourceware.org
Wed Nov 26 22:42:37 GMT 2025


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=2600d751c34d127786fa50ab32c9d4f589181ee6

commit 2600d751c34d127786fa50ab32c9d4f589181ee6
Author: Alan Modra <amodra@gmail.com>
Date:   Thu Nov 27 08:54:43 2025 +1030

    Tidy .eh_frame rawsize manipulation
    
    bfd_elf_discard_info is only called once.  Well, it was until commit
    9b854f169df9 introduced cmdline_emit_object_only_section, but I think
    and hope that function does enough reinitialisation to not cause a
    problem.  There would be a problem if bfd_elf_discard_info was called
    iteratively, shrinking an eh_frame section on the first pass, then
    further shrinking on another pass.  That's because
    _bfd_elf_discard_section_eh_frame uses rawsize to store the last
    section size, which is against the general rules for input sections.
    rawsize needs to be kept as the initial size to be able to read
    section contents again (or you'd need to cache the edited contents).
    Other eh_frame functions would break too.
    
    So this tidy makes it obvious when looking at
    _bfd_elf_discard_section_eh_frame alone that rawsize is only set once,
    to the initial size.  There are no functional changes here.
    
            * elf-bfd.h (_bfd_elf_discard_section_eh_frame): Update decl.
            * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Return
            an int status.  Don't set rawsize unless it is zero.
            * elflink.c (bfd_elf_discard_info): Use new return status
            from _bfd_elf_discard_section_eh_frame rather than comparing
            section size with rawsize.

Diff:
---
 bfd/elf-bfd.h      |  2 +-
 bfd/elf-eh-frame.c | 16 +++++++++-------
 bfd/elflink.c      |  9 ++++++---
 3 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index 3a7784e3bcd..b0f16fd1871 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -2542,7 +2542,7 @@ extern void _bfd_elf_parse_eh_frame
 extern bool _bfd_elf_end_eh_frame_parsing
   (struct bfd_link_info *info) ATTRIBUTE_HIDDEN;
 
-extern bool _bfd_elf_discard_section_eh_frame
+extern int _bfd_elf_discard_section_eh_frame
   (bfd *, struct bfd_link_info *, asection *,
    bool (*) (bfd_vma, void *), struct elf_reloc_cookie *) ATTRIBUTE_HIDDEN;
 extern bool _bfd_elf_adjust_eh_frame_global_symbol
diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c
index 0212523cc79..91d08bb9e30 100644
--- a/bfd/elf-eh-frame.c
+++ b/bfd/elf-eh-frame.c
@@ -1493,11 +1493,12 @@ adjust_eh_frame_local_symbols (const asection *sec,
 }
 
 /* This function is called for each input file before the .eh_frame
-   section is relocated.  It discards duplicate CIEs and FDEs for discarded
-   functions.  The function returns TRUE iff any entries have been
-   deleted.  */
+   section is relocated.  It discards duplicate CIEs and FDEs for
+   discarded functions.  The function returns 0 when no changes are
+   made, 1 when .eh_frame data has been edited and 2 when the editing
+   results in a section size change.  */
 
-bool
+int
 _bfd_elf_discard_section_eh_frame
    (bfd *abfd, struct bfd_link_info *info, asection *sec,
     bool (*reloc_symbol_deleted_p) (bfd_vma, void *),
@@ -1622,10 +1623,11 @@ _bfd_elf_discard_section_eh_frame
 
   eh_alignment = 4;
   offset = (offset + eh_alignment - 1) & -eh_alignment;
-  sec->rawsize = sec->size;
+  if (sec->rawsize == 0)
+    sec->rawsize = sec->size;
+  if (sec->size != offset)
+    changed = 2;
   sec->size = offset;
-  if (sec->size != sec->rawsize)
-    changed = 1;
 
   if (changed)
     {
diff --git a/bfd/elflink.c b/bfd/elflink.c
index ec34c8abcf7..cf593b344f4 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -15186,6 +15186,8 @@ bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info)
 
       for (i = o->map_head.s; i != NULL; i = i->map_head.s)
 	{
+	  int r;
+
 	  if (i->size == 0)
 	    continue;
 
@@ -15197,12 +15199,13 @@ bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info)
 	    return -1;
 
 	  _bfd_elf_parse_eh_frame (abfd, info, i, &cookie);
-	  if (_bfd_elf_discard_section_eh_frame (abfd, info, i,
+	  r = _bfd_elf_discard_section_eh_frame (abfd, info, i,
 						 bfd_elf_reloc_symbol_deleted_p,
-						 &cookie))
+						 &cookie);
+	  if (r)
 	    {
 	      eh_changed = 1;
-	      if (i->size != i->rawsize)
+	      if (r >= 2)
 		changed = 1;
 	    }


More information about the Binutils-cvs mailing list