From: Alan Modra Date: Tue, 16 Dec 2025 21:30:24 +0000 (+1030) Subject: PR 33721 load/store of misaligned address X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=44e7622937280a0a7c679949fc313d6ffc710701;p=thirdparty%2Fbinutils-gdb.git PR 33721 load/store of misaligned address This fixes PR33721 by a common technique of declaring a packed struct to access unaligned integer fields. (See eg. linux kernel include/vdso/unaligned.h) I've tidied the PR29856 fix for a similar bug too (not that there was anything wrong with that fix). PR 33721 PR 29856 * sframe.c (flip_fre_start_address): Use a packed struct to access 2-byte and 4-byte unaligned fields. Make addr a void*. (sframe_decode_fre_start_address): Similarly, and remove unnecessary casts. Always set *fre_start_addr. --- diff --git a/libsframe/sframe.c b/libsframe/sframe.c index 0dcc782b1f6..3a02a76a2a9 100644 --- a/libsframe/sframe.c +++ b/libsframe/sframe.c @@ -311,17 +311,17 @@ sframe_header_sanity_check_p (const sframe_header *hp) /* Flip the start address pointed to by FP. */ static void -flip_fre_start_address (char *addr, uint32_t fre_type) +flip_fre_start_address (void *addr, uint32_t fre_type) { if (fre_type == SFRAME_FRE_TYPE_ADDR2) { - uint16_t *start_addr = (uint16_t *)addr; - swap_thing (*start_addr); + struct { uint16_t x; } ATTRIBUTE_PACKED *p = addr; + swap_thing (p->x); } else if (fre_type == SFRAME_FRE_TYPE_ADDR4) { - uint32_t *start_addr = (uint32_t *)addr; - swap_thing (*start_addr); + struct { uint32_t x; } ATTRIBUTE_PACKED *p = addr; + swap_thing (p->x); } } @@ -938,42 +938,34 @@ sframe_frame_row_entry_copy (sframe_frame_row_entry *dst, Returns 0 on success, SFRAME_ERR otherwise. */ static int -sframe_decode_fre_start_address (const char *fre_buf, +sframe_decode_fre_start_address (const void *fre_buf, uint32_t *fre_start_addr, uint32_t fre_type) { uint32_t saddr = 0; int err = 0; - size_t addr_size = 0; - - addr_size = sframe_fre_start_addr_size (fre_type); if (fre_type == SFRAME_FRE_TYPE_ADDR1) { - uint8_t *uc = (uint8_t *)fre_buf; - saddr = (uint32_t)*uc; + const uint8_t *uc = fre_buf; + saddr = *uc; } else if (fre_type == SFRAME_FRE_TYPE_ADDR2) { - uint16_t *ust = (uint16_t *)fre_buf; - /* SFrame is an unaligned on-disk format. Using memcpy helps avoid the - use of undesirable unaligned loads. See PR libsframe/29856. */ - uint16_t tmp = 0; - memcpy (&tmp, ust, addr_size); - saddr = (uint32_t)tmp; + /* SFrame is an unaligned on-disk format. See PR libsframe/29856. */ + const struct { uint16_t x; } ATTRIBUTE_PACKED *p = fre_buf; + saddr = p->x; } else if (fre_type == SFRAME_FRE_TYPE_ADDR4) { - uint32_t *uit = (uint32_t *)fre_buf; - uint32_t tmp = 0; - memcpy (&tmp, uit, addr_size); - saddr = (uint32_t)tmp; + const struct { uint32_t x; } ATTRIBUTE_PACKED *p = fre_buf; + saddr = p->x; } else - return sframe_set_errno (&err, SFRAME_ERR_INVAL); + sframe_set_errno (&err, SFRAME_ERR_INVAL); *fre_start_addr = saddr; - return 0; + return err; } /* Decode a frame row entry FRE which starts at location FRE_BUF. The function