[PATCH v2 7/7] Fix the calculation of the function length

Evgeny Karpov Evgeny.Karpov@microsoft.com
Thu Jul 24 10:23:49 GMT 2025


Wednesday, July 23
Richard Earnshaw (lists) <Richard.Earnshaw@arm.com> wrote:

>> Repro case:
>> 
>> .text
>> .seh_proc	test
>> .seh_endprologue
>>     mov x0, xzr
>>     .align 2 // Once this is removed, the expression for function size can be evaluated correctly
>>     ret
>> .seh_endproc
>> 
>
> I don't think it's that uncommon to see code with alignment of branch targets.  For example,
>
> .text
>      .p2align 4  // 16-byte alignment so that func is at start of cache line
> func:
>      // code
>      b  Lsomewhere
>      // no fall-through path
>      .p2align 4  // 16-byte alignment so that Lsomewhere_else is at start of cache line
> Lsomewhere_else:
>      // more code
>
> We certainly want to support that.  See, for example, -falign-labels and -falign-loops in the gcc manual.
>
> Maybe your problem is that you're trying to calculate the function size for the seh data too early, before the frags have been consolidated: the intra-section alignment data should all be replaced with appropriate padding before the object file is emitted, so all offsets within a function become fixed.

Thanks. It was exactly this case. This patch is no longer needed, and the issue 
will be addressed by adding the change below to [Patch] Write SEH records to pdata/xdata

Regards,
Evgeny

diff --git a/gas/config/obj-coff-seh.c b/gas/config/obj-coff-seh.c
index 75b45b8d4dd..b05153bfe81 100644
--- a/gas/config/obj-coff-seh.c
+++ b/gas/config/obj-coff-seh.c
@@ -559,6 +559,24 @@ do_seh_endproc (void)
 {
   seh_ctx_cur->end_addr = symbol_temp_new_now ();

+#if defined (COFFAARCH64)
+/* Fragment alignment should be handled before writing unwinding
+   information to the .pdata/.xdata sections. This is required to
+   accurately calculate the function size, which is used to split
+   the function into multiple fragments if it is too large. */
+
+  struct frag * current_frag = frchain_now->frch_root;
+  while(current_frag)
+    {
+      if (current_frag->fr_type == rs_align_code)
+       {
+         HANDLE_ALIGN (now_seg, current_frag);
+         current_frag->fr_type = rs_fill;
+       }
+      current_frag = current_frag->fr_next;
+    }
+#endif
+


More information about the Binutils mailing list