[PATCH v4 5/7] Write SEH records to pdata/xdata

Jan Beulich jbeulich@suse.com
Mon Feb 2 16:39:36 GMT 2026


On 02.02.2026 16:55, Evgeny Karpov wrote:
> On Fri, Oct 17, 2025, Jan Beulich wrote:
>> On 15.08.2025 00:50, Evgeny Karpov wrote:
>>> +  fragS *start_frag, *end_frag;
>>> +  addressT start_value, end_value;
>>> +  start_frag = symbol_get_frag_and_value (seh_ctx->start_addr, &start_value);
>>> +  end_frag = symbol_get_frag_and_value (seh_ctx->end_addr, &end_value);
>>> +  offsetT offset;
>>> +  frag_offset_ignore_align_p (end_frag, start_frag, &offset);
>>> +  start_value += offset / OCTETS_PER_BYTE;
>>> +  offset = end_value - start_value;
>>> +
>>> +  if (offset < 0)
>>> +    {
>>> +      as_bad (_("the function size expression for %s "
>>> +	      "does not evaluate to a non-negative value"),
>>> +	      S_GET_NAME (seh_ctx->start_addr));
>>> +      return;
>>> +    }
>>> +
>>> +  uintptr_t func_size = offset;
>>> +
>>> +  const uint32_t max_frag_size = ((1 << 18) - 1) << 2;
>>
>> Where does this boundary come from?
> 
> https://learn.microsoft.com/en-us/cpp/build/arm64-exception-handling?view=msvc-170#large-functions
> The large functions should be split into fragments smaller than 1MB.

Please either introduce a #define (where the name would suitably clarify
the purpose) or add a comment.

>>> +	{
>>> +	  prolog_insruction_count = i + 1;
>>> +	  break;
>>> +	}
>>> +    }
>>> +
>>> +  if (seh_ctx->aarch64_ctx.epilogue_scopes_count)
>>> +    prolog_size = seh_ctx->aarch64_ctx.epilogue_scopes[0].epilogue_start_index;
>>> +  else
>>> +    prolog_size = seh_ctx->aarch64_ctx.unwind_codes_byte_count;
>>> +
>>> +  seh_aarch64_func_fragment *fragment;
>>> +  fragment = &seh_ctx->aarch64_ctx.func_fragment;
>>
>> Why not right as initializer of the variable? (Apparently I overlooked
>> similar anomalies already further up.)
> 
> The reason is the 80 characters limit per line. Any other preferable style?

  seh_aarch64_func_fragment *fragment
    = &seh_ctx->aarch64_ctx.func_fragment;

However,

  seh_aarch64_func_fragment *fragment = &seh_ctx->aarch64_ctx.func_fragment;

still stays under 80 cols anyway.

>>> +  while (true)
>>> +    {
>>> +      fragment->xdata_addr = symbol_temp_new_now ();
>>> +      fragment->offset = fragment_offset;
>>> +      fragment->next = NULL;
>>> +
>>> +      uintptr_t frag_size = func_size - fragment_offset;
>>> +      if (frag_size > max_frag_size)
>>> +	frag_size = max_frag_size;
>>> +
>>> +      bool is_first_frag = fragment_offset == 0;
>>> +      bool is_last_frag = (fragment_offset + frag_size) == func_size;
>>> +
>>> +      if (!is_fragmented_function)
>>> +	last_fragment_scope = seh_ctx->aarch64_ctx.epilogue_scopes_count;
>>> +      else
>>> +	{
>>> +	  first_fragment_scope = last_fragment_scope;
>>> +	  for (unsigned int i = first_fragment_scope;
>>> +	       i < seh_ctx->aarch64_ctx.epilogue_scopes_count; ++i)
>>> +	    {
>>> +	      const seh_aarch64_epilogue_scope *scope;
>>> +	      scope = seh_ctx->aarch64_ctx.epilogue_scopes;
>>> +	      scope += i;
>>> +	      if (scope->epilogue_start_offset >= (fragment_offset + frag_size))
>>> +		break;
>>> +
>>> +	      if (scope->epilogue_end_offset >= (fragment_offset + frag_size))
>>> +		{
>>> +		  frag_size = scope->epilogue_start_offset - fragment_offset;
>>> +		  break;
>>> +		}
>>> +
>>> +	      if (scope->epilogue_start_offset >= fragment_offset)
>>> +		last_fragment_scope = i + 1;
>>> +	    }
>>> +	}
>>> +
>>> +      seh_aarch64_xdata_header *header = &seh_ctx->aarch64_ctx.xdata_header;
>>> +      const
>>> +      seh_aarch64_epilogue_scope *scopes =
>>> seh_ctx->aarch64_ctx.epilogue_scopes;
>>> +
>>> +      header->func_length = frag_size >> 2;
>>
>> Another such magic number.
> 
> This is how the function length is encoded.
> https://learn.microsoft.com/en-us/cpp/build/arm64-exception-handling?view=msvc-170#xdata-records

In which case, like above, use a suitably named #define or add a comment,
please. Especially in case constants are used more than once, a #define is
pretty clearly preferred.

Jan


More information about the Binutils mailing list