[binutils-gdb] PR 33721 load/store of misaligned address
Alan Modra
amodra@sourceware.org
Tue Dec 16 21:31:23 GMT 2025
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=44e7622937280a0a7c679949fc313d6ffc710701
commit 44e7622937280a0a7c679949fc313d6ffc710701
Author: Alan Modra <amodra@gmail.com>
Date: Wed Dec 17 08:00:24 2025 +1030
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:
---
libsframe/sframe.c | 38 +++++++++++++++-----------------------
1 file changed, 15 insertions(+), 23 deletions(-)
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
More information about the Binutils-cvs
mailing list