[PATCH v3 3/3] sframe: FDE function start address relative to SFrame section

Indu Bhagat indu.bhagat@oracle.com
Wed Mar 5 14:24:10 GMT 2025


On 2/28/25 5:32 AM, Jens Remus wrote:
> The SFrame FDE sfde_func_start_address field is specified to contain
> the function offset from .sframe section.  This is true in executables
> and shared libraries after final link.  In assembler generated objects
> it contained the function offset from SFrame FDE (using a PC-relative
> relocation) and the linker performed a respective fixup when merging
> the .sframe sections.
> 
> Change the assembler to emit sfde_func_start_address relative from the
> .sframe section.  Change the linker to only apply the output .sframe
> section offset as fixup when merging the sections.
> 
> While at it enhance the comments in the code, fix a typo in SFD_INFO,
> and remove commented out debugging code.
> 

Thanks for the patch.

I would like to consider this patch along with some other patches that I 
have for fixing the outstanding SFrame issues (PR 32589) and its 
repercussions on relocatable links (PR 32666) and --gc-sections.

I think it is better to review this change along with the fixes for the 
above issues.  I will include this patch in a separate series I plan to 
post soon.

Thanks
Indu

> gas/
> 	* gen-sframe.c (output_sframe_internal): Create temporary symbol
> 	for start of SFrame section.  Pass it to output_sframe_funcdesc.
> 	(output_sframe_funcdesc): Emit SFrame FDE function start address
> 	as offset from SFrame section instead of FDE.
> 
> bfd/
> 	* elf-sframe.c (_bfd_elf_merge_section_sframe): Fixup SFrame FDE
> 	function start address by adding output .sframe offset.  Enhance
> 	comments.
> 	(sframe_decoder_set_func_reloc_index): Correct typo in comment.
> 
> Signed-off-by: Jens Remus <jremus@linux.ibm.com>
> ---
> 
> Notes (jremus):
>      Changes in V3:
>      - New patch.  Replaces V2 patch ("sframe: Enhance comments and
>        documentation on FDE function start address").
> 
>   bfd/elf-sframe.c | 44 ++++++++++++++++++++++++++------------------
>   gas/gen-sframe.c | 11 +++++++----
>   2 files changed, 33 insertions(+), 22 deletions(-)
> 
> diff --git a/bfd/elf-sframe.c b/bfd/elf-sframe.c
> index 97e007345152..83611921e015 100644
> --- a/bfd/elf-sframe.c
> +++ b/bfd/elf-sframe.c
> @@ -93,7 +93,7 @@ sframe_decoder_set_func_reloc_index (struct sframe_dec_info *sfd_info,
>       sfd_info->sfd_func_bfdinfo[func_idx].func_reloc_index = reloc_index;
>   }
>   
> -/* Initialize the set of additional information in CFD_INFO,
> +/* Initialize the set of additional information in SFD_INFO,
>      needed for linking SEC.  Returns TRUE if setup is done successfully.  */
>   
>   static bool
> @@ -446,27 +446,28 @@ _bfd_elf_merge_section_sframe (bfd *abfd,
>   	    {
>   	      if (!(sec->flags & SEC_LINKER_CREATED))
>   		{
> -		  /* Get relocated contents by reading the value of the
> -		     relocated function start address at the beginning of the
> -		     function descriptor entry.  */
> +		  /* Offset to SFrame FDE sfde_func_start_address from input
> +		     .sframe section.  It contains the relocated function
> +		     offset from input .sframe section.  */
>   		  r_offset = sframe_decoder_get_func_r_offset (sfd_info, i);
>   		}
>   	      else
>   		{
>   		  /* Expected to land here when SFrame stack trace info is
> -		     created dynamically for the .plt* sections.  These
> -		     sections are expected to have upto two SFrame FDE entries.
> +		     created dynamically for the .plt* sections.  These .sframe
> +		     sections are expected to have upto two SFrame FDEs.
>   		     Although the code should work for > 2,  leaving this
>   		     assert here for safety.  */
>   		  BFD_ASSERT (num_fidx <= 2);
> -		  /* For the first entry, we know the offset of the SFrame FDE's
> -		     sfde_func_start_address.  Side note: see how the value
> -		     of PLT_SFRAME_FDE_START_OFFSET is also set to the
> -		     same.  */
> +		  /* Offset to the first linker-generated SFrame FDE (for PLT0)
> +		     sfde_func_start_address from input .sframe section.  It
> +		     contains the PLT0 offset from FDE.  NB: See how it is set
> +		     using PLT_SFRAME_FDE_START_OFFSET.  */
>   		  r_offset = sframe_decoder_get_hdr_size (sfd_ctx);
> -		  /* For any further SFrame FDEs, the generator has already put
> -		     in an offset in place of sfde_func_start_address of the
> -		     corresponding FDE.  We will use it by hand to relocate.  */
> +		  /* Offset to any subsequent linker-generated SFrame FDE (for
> +		     PLTn) sfde_func_start_address from input .sframe section.
> +		     It contains the PLTn offset from PLT0.  We will use it by
> +		     hand to relocate.  */
>   		  if (i > 0)
>   		    {
>   		      pltn_r_offset
> @@ -475,15 +476,22 @@ _bfd_elf_merge_section_sframe (bfd *abfd,
>   		    }
>   		}
>   
> -	      /* Get the SFrame FDE function start address after relocation.  */
> +	      /* Get the SFrame FDE sfde_func_start_address value after
> +		 relocation.  In object files it is the function offset
> +		 from input .sframe section.  For linker-generated FDE
> +		 it is the PLT0 offset from FDE.  */
>   	      address = sframe_read_value (abfd, contents, r_offset, 4);
> +	      /* For linker-generated PLTn add the PLTn offset from PLT0.  */
>   	      if (pltn_reloc_by_hand)
>   		address += sframe_read_value (abfd, contents,
>   					      pltn_r_offset, 4);
> -	      address += (sec->output_offset + r_offset);
> -
> -	      /* FIXME For testing only. Cleanup later.  */
> -	      // address += (sec->output_section->vma);
> +	      /* Fixup by adding the output .sframe section offset.  For
> +		 linker-generated FDE additionally add the first FDE
> +		 offset from input .sframe section.  */
> +	      if (!(sec->flags & SEC_LINKER_CREATED))
> +		address += sec->output_offset;
> +	      else
> +		address += (sec->output_offset + r_offset);
>   
>   	      func_start_addr = address;
>   	    }
> diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c
> index dd5fb25e367f..b50c6613c5a6 100644
> --- a/gas/gen-sframe.c
> +++ b/gas/gen-sframe.c
> @@ -607,7 +607,8 @@ output_sframe_row_entry (symbolS *fde_start_addr,
>   }
>   
>   static void
> -output_sframe_funcdesc (symbolS *start_of_fre_section,
> +output_sframe_funcdesc (symbolS *start_of_sframe_section,
> +			symbolS *start_of_fre_section,
>   			symbolS *fre_symbol,
>   			struct sframe_func_entry *sframe_fde)
>   {
> @@ -618,10 +619,10 @@ output_sframe_funcdesc (symbolS *start_of_fre_section,
>     dw_fde_start_addrS = get_dw_fde_start_addrS (sframe_fde->dw_fde);
>     dw_fde_end_addrS = get_dw_fde_end_addrS (sframe_fde->dw_fde);
>   
> -  /* Start address of the function.  */
> +  /* Start address of the function (function offset from .sframe section).  */
>     exp.X_op = O_subtract;
>     exp.X_add_symbol = dw_fde_start_addrS; /* to location.  */
> -  exp.X_op_symbol = symbol_temp_new_now (); /* from location.  */
> +  exp.X_op_symbol = start_of_sframe_section; /* from location.  */
>     exp.X_add_number = 0;
>     emit_expr (&exp, sizeof_member (sframe_func_desc_entry,
>   				  sfde_func_start_address));
> @@ -672,6 +673,7 @@ output_sframe_internal (void)
>     expressionS exp;
>     unsigned int i = 0;
>   
> +  symbolS *start_of_sframe_section = symbol_temp_new_now ();
>     symbolS *end_of_frame_hdr;
>     symbolS *end_of_frame_section;
>     symbolS *start_of_func_desc_section;
> @@ -763,7 +765,8 @@ output_sframe_internal (void)
>     i = 0;
>     for (sframe_fde = all_sframe_fdes; sframe_fde; sframe_fde = sframe_fde->next)
>       {
> -      output_sframe_funcdesc (start_of_fre_section,
> +      output_sframe_funcdesc (start_of_sframe_section,
> +			      start_of_fre_section,
>   			      fre_symbols[i], sframe_fde);
>         i += sframe_fde->num_fres;
>       }



More information about the Binutils mailing list