[PATCH] objdump: sframe: fix multiple emission of SFrame and DWARF Frame

Indu Bhagat indu.bhagat@oracle.com
Thu Feb 5 09:02:52 GMT 2026


On 2/3/26 11:07 PM, Jan Beulich wrote:
> On 03.02.2026 23:37, Indu Bhagat via Binutils wrote:
>> Currently, when a user specifies both -WF (to dump DWARF Frame) and
>> --sframe, the dump_dwarf () call is triggered twice,
>>
>> First, in dump_bfd ():
>>    if (dump_dwarf_section_info)
>>      dump_dwarf (abfd, is_mainfile);
>>
>> And then again in dump_bfd () via:
>>     if (dump_sframe_section_info)
>>       dump_sframe_section (abfd, dump_sframe_section_name, is_mainfile);
>> Where dump_sframe_section () itself invokes dump_dwarf () to emit SFrame
>> section.
>>
>> The original intent of making dump_sframe_section () to invoke
>> dump_dwarf () was to reuse the existing (DWARF) machinery for relocation
>> and emission of SFrame section (along with DWARF sections).  But this
>> may cause duplicate emission as noted above (PR 33806).
>>
>> So, carve out the necessary work into dump_sframe_section () to make it
>> not invoke dump_dwarf (): explicitly load the SFrame section and then
>> invoke the associated display function directly.  This ensures that the
>> SFrame textual dump is emitted exactly once as intended.
>>
>> Additionally, this patch removes:
>>    - the temporary "sframe-internal-only" debug option because it not
>>      needed anymore, now that we dont use dump_dwarf () for SFrame dumping
>>      anymore.
>>    - stubs from dump_dwarf_section () specific to SFrame, as it is not
>>      called for it anymore.
>>
>> While at it, xstrdup consistently and free the dump_sframe_section_name
>> var.
>>
>> Update the existing sframe-func.s to ensure .eh_frame section is emitted
>> as well.  Add new test objdump-sframe-2.d to verify that textual dump
>> using objdump contains single textual dumps of .eh_frame and .sframe (if
>> both --sframe and -WF are specified).
>>
>> PR libsframe/33806
>>
>> binutils/
>> 	PR libsframe/33806
>> 	* dwarf.c (debug_option_table): Remove sframe-internal-only.
>> 	* objdump.c (dump_sframe_section): Call display function
>> 	directly instead of dump_dwarf.
>> 	(dump_bfd): Update call to dump_sframe_section.
>> 	(main): Remove 'sframe-internal-only' hack.
>> binutils/testsuite/
>> 	* binutils-all/x86-64/sframe-func.s: Emit .eh_frame section as
>> 	well.
>> 	* binutils-all/x86-64/objdump-sframe-2.d: New test.
>> ---
>>   binutils/dwarf.c                              |  1 -
>>   binutils/objdump.c                            | 69 +++++++++----------
>>   .../binutils-all/x86-64/objdump-sframe-2.d    | 33 +++++++++
>>   .../binutils-all/x86-64/sframe-func.s         |  1 -
>>   4 files changed, 66 insertions(+), 38 deletions(-)
>>   create mode 100644 binutils/testsuite/binutils-all/x86-64/objdump-sframe-2.d
> 
> Largely okay, and even a negative diffstat for objdump.c alone. A nit and a few
> remarks below, though.
> 
>> @@ -4983,33 +4979,40 @@ dump_ctf (bfd *abfd ATTRIBUTE_UNUSED, const char *sect_name ATTRIBUTE_UNUSED,
>>   #endif
>>   
>>   static void
>> -dump_sframe_section (bfd *abfd, const char *sect_name, bool is_mainfile)
>> +dump_sframe_section (bfd *abfd, const char *sect_name)
>>   
>>   {
>>     /* Error checking for user provided SFrame section name, if any.  */
>> -  if (sect_name)
>> +  asection *sec = bfd_get_section_by_name (abfd, sect_name);
>> +  if (sec == NULL)
>>       {
>> -      asection *sec = bfd_get_section_by_name (abfd, sect_name);
>> -      if (sec == NULL)
>> -	{
>> -	  printf (_("No %s section present\n\n"), sanitize_string (sect_name));
>> -	  return;
>> -	}
>> -      /* Starting with Binutils 2.45, SFrame sections have section type
>> -	 SHT_GNU_SFRAME.  For SFrame sections from Binutils 2.44 or earlier,
>> -	 check explcitly for SFrame sections of type SHT_PROGBITS and name
>> -	 ".sframe" to allow them.  */
>> -      else if (bfd_get_flavour (abfd) != bfd_target_elf_flavour
>> -	       || (elf_section_type (sec) != SHT_GNU_SFRAME
>> -		   && !(elf_section_type (sec) == SHT_PROGBITS
>> -			&& strcmp (sect_name, ".sframe") == 0)))
>> -	{
>> -	  printf (_("Section %s does not contain SFrame data\n\n"),
>> -		  sanitize_string (sect_name));
>> -	  return;
>> -	}
>> +      printf (_("No %s section present\n\n"), sanitize_string (sect_name));
>> +      return;
>> +    }
>> +  /* Starting with Binutils 2.45, SFrame sections have section type
>> +     SHT_GNU_SFRAME.  For SFrame sections from Binutils 2.44 or earlier,
>> +     check explcitly for SFrame sections of type SHT_PROGBITS and name
>> +     ".sframe" to allow them.  */
>> +  else if (bfd_get_flavour (abfd) != bfd_target_elf_flavour
>> +	   || (elf_section_type (sec) != SHT_GNU_SFRAME
>> +	       && !(elf_section_type (sec) == SHT_PROGBITS
>> +		    && strcmp (sect_name, ".sframe") == 0)))
>> +    {
>> +      printf (_("Section %s does not contain SFrame data\n\n"),
>> +	      sanitize_string (sect_name));
>> +      return;
>>       }
>> -  dump_dwarf (abfd, is_mainfile);
>> +
>> +  /* Instead of invoking dump_dwarf () here, load the section and invoke the
>> +     display function directly.  Otherwise, the textual dump may contain
>> +     duplicate output due to two invocations of dump_dwarf ().  See PR
>> +     libsframe/33806.  */
>> +  if (!load_specific_debug_section (sframe, sec, (void*) abfd))
> 
> Nit: Blank after * please.
> 

OK.

> I'm also uncertain about the comment. With the call to dump_dwarf() gone, I see
> no reason to mention that function at all. SFrame isn't Dwarf, after all. Using
> it was an attempt to take a shortcut, but as both the bug report and the
> diffstat show, that wasn't really the way to go. As a result, I don't see a
> need for a comment (to the effect it presently has) here at all.
> 

You're right.  I was overthinking perhaps, this doesnt vouch for a code 
comment.  The explanation in commit log should suffice for posterity on 
what not to do.

>> --- /dev/null
>> +++ b/binutils/testsuite/binutils-all/x86-64/objdump-sframe-2.d
>> @@ -0,0 +1,33 @@
>> +#name: objdump sframe with eh_frame
>> +#source: sframe-func.s
>> +#as: --gsframe
>> +#objdump: --sframe -WF
>> +#target: x86_64-*-*
>> +#xfail: ![gas_sframe_check]
> 
> Why xfail? A target not supporting SFrame will never pass this test. It thus
> shouldn't be a valid target for this test in the first place.
> 

SFrame is not supported for x32.  gas_sframe_check will fail for x32, 
and the test is reported as XFAIL.  May be its better to use '#notarget: 
x86_64-*-gnux32' instead of '#xfail: ![gas_sframe_check]' ?

>> --- a/binutils/testsuite/binutils-all/x86-64/sframe-func.s
>> +++ b/binutils/testsuite/binutils-all/x86-64/sframe-func.s
>> @@ -1,4 +1,3 @@
>> -	.cfi_sections .sframe
>>   	.cfi_startproc
>>   	.long 8
>>   	.cfi_def_cfa_offset 16
> 
> You must be altering an existing test here. If that line can be easily removed
> without any compensation, why was it there in the first place?
> 

Looks to be a carry over from a template from which this was copied in 
the first place.  The current users of sframe-func.s 
(binutils-all/x86-64/readelf-sframe-01.d and 
binutils-all/x86-64/objdump-sframe-01.d) are explicitly invoking 
--gsframe, like the objdump-sframe-2.d above, so the '.cfi_sections 
.sframe' was redundant for existing tests.

Thanks for reviewing



More information about the Binutils mailing list