On Mär 25 2026, Farid Zakaria wrote:
> @@ -437,23 +446,45 @@ find_fde_tail (_Unwind_Ptr pc,
> /* Shouldn't happen. */
> if (fde_count == 0)
> return NULL;
> - if ((((_Unwind_Ptr) p) & 3) == 0)
> + if ((((_Unwind_Ptr) p) & align_mask) == 0)
> {
> - struct fde_table {
> - signed initial_loc __attribute__ ((mode (SI)));
> - signed fde __attribute__ ((mode (SI)));
> - };
> - const struct fde_table *table = (const struct fde_table *) p;
> + const unsigned char *table = p;
> size_t lo, hi, mid;
> _Unwind_Ptr data_base = (_Unwind_Ptr) hdr;
> fde *f;
> unsigned int f_enc, f_enc_size;
> _Unwind_Ptr range;
>
> + /* Read a signed field from the table. For sdata4 entries
> + these are mode (SI) (32-bit); for sdata8, mode (DI) (64-bit).
> + Use the packed unaligned union from unwind-pe.h types. */
> + union table_entry {
> + signed s4 __attribute__ ((mode (SI)));
> + signed s8 __attribute__ ((mode (DI)));
> + } __attribute__ ((__packed__));
> +
> + /* Read the initial_loc field at a given table index. */
> +#define TABLE_LOC(i) \
> + (is_sdata8 \
> + ? (_Unwind_Ptr) ((const union table_entry *) \
> + (table + (i) * entry_size))->s8 \
> + : (_Unwind_Ptr) ((const union table_entry *) \
> + (table + (i) * entry_size))->s4)
> +
> + /* Read the fde field at a given table index. */
> +#define TABLE_FDE(i) \
> + (is_sdata8 \
> + ? (_Unwind_Ptr) ((const union table_entry *) \
> + (table + (i) * entry_size \
> + + field_size))->s8 \
> + : (_Unwind_Ptr) ((const union table_entry *) \
> + (table + (i) * entry_size \
> + + field_size))->s4)
Why does that need to use unaligned accesses when the table pointer is
guaranteed to be aligned?
--
Andreas Schwab, SUSE Labs, [email protected]
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."