@samitouri / QOSamiQemu / commits / 93cf730514

target/hexagon: raise SIGBUS on unaligned scalar loads

hexagon-linux-user had no enforcement of alignment for scalar load exceptions, and unaligned loads silently succeeded instead of raising SIGBUS. Add MO_ALIGN to the MEM_LOAD* macros, the locked-load and load-frame helpers in genptr.c, and the idef-parser's fLOAD. Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> Reviewed-by: Matheus Tavares Bernardino <matheus.bernardino@oss.qualcomm.com> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>

Brian Cain committed Jul 13, 2026 at 18:09 UTC 93cf73051435c8695d7d0b04dbad4bb8d5339dd2
3 files changed +20 -14
target/hexagon/genptr.c
+3 -3
@@ -470,14 +470,14 @@ void gen_set_byte_i64(int N, TCGv_i64 result, TCGv src)
470
471 static inline void gen_load_locked4u(TCGv dest, TCGv vaddr, int mem_index)
472 {
473 - tcg_gen_qemu_ld_tl(dest, vaddr, mem_index, MO_LE | MO_UL);
473 + tcg_gen_qemu_ld_tl(dest, vaddr, mem_index, MO_LE | MO_UL | MO_ALIGN);
474 tcg_gen_mov_tl(hex_llsc_addr, vaddr);
475 tcg_gen_mov_tl(hex_llsc_val, dest);
476 }
477
478 static inline void gen_load_locked8u(TCGv_i64 dest, TCGv vaddr, int mem_index)
479 {
480 - tcg_gen_qemu_ld_i64(dest, vaddr, mem_index, MO_LE | MO_UQ);
480 + tcg_gen_qemu_ld_i64(dest, vaddr, mem_index, MO_LE | MO_UQ | MO_ALIGN);
481 tcg_gen_mov_tl(hex_llsc_addr, vaddr);
482 tcg_gen_mov_i64(hex_llsc_val_i64, dest);
483 }
@@ -890,7 +890,7 @@ static void gen_load_frame(DisasContext *ctx, TCGv_i64 frame, TCGv EA)
890 {
891 Insn *insn = ctx->insn; /* Needed for CHECK_NOSHUF */
892 CHECK_NOSHUF(EA, 8);
893 - tcg_gen_qemu_ld_i64(frame, EA, ctx->mem_idx, MO_LE | MO_UQ);
893 + tcg_gen_qemu_ld_i64(frame, EA, ctx->mem_idx, MO_LE | MO_UQ | MO_ALIGN);
894 }
895
896 /* Stack overflow check */
target/hexagon/idef-parser/parser-helpers.c
+1 -1
@@ -1770,7 +1770,7 @@ void gen_load(Context *c, YYLTYPE *locp, HexValue *width,
1770 if (signedness == SIGNED) {
1771 OUT(c, locp, " | MO_SIGN");
1772 }
1773 - OUT(c, locp, " | MO_LE);\n");
1773 + OUT(c, locp, " | MO_LE | MO_ALIGN);\n");
1774 }
1775
1776 void gen_store(Context *c, YYLTYPE *locp, HexValue *width, HexValue *ea,
target/hexagon/macros.h
+16 -10
@@ -106,37 +106,37 @@
106 #define MEM_LOAD1s(DST, VA) \
107 do { \
108 CHECK_NOSHUF(VA, 1); \
109 - tcg_gen_qemu_ld_tl(DST, VA, ctx->mem_idx, MO_SB); \
109 + tcg_gen_qemu_ld_tl(DST, VA, ctx->mem_idx, MO_SB | MO_ALIGN); \
110 } while (0)
111 #define MEM_LOAD1u(DST, VA) \
112 do { \
113 CHECK_NOSHUF(VA, 1); \
114 - tcg_gen_qemu_ld_tl(DST, VA, ctx->mem_idx, MO_UB); \
114 + tcg_gen_qemu_ld_tl(DST, VA, ctx->mem_idx, MO_UB | MO_ALIGN); \
115 } while (0)
116 #define MEM_LOAD2s(DST, VA) \
117 do { \
118 CHECK_NOSHUF(VA, 2); \
119 - tcg_gen_qemu_ld_tl(DST, VA, ctx->mem_idx, MO_LE | MO_SW); \
119 + tcg_gen_qemu_ld_tl(DST, VA, ctx->mem_idx, MO_LE | MO_SW | MO_ALIGN); \
120 } while (0)
121 #define MEM_LOAD2u(DST, VA) \
122 do { \
123 CHECK_NOSHUF(VA, 2); \
124 - tcg_gen_qemu_ld_tl(DST, VA, ctx->mem_idx, MO_LE | MO_UW); \
124 + tcg_gen_qemu_ld_tl(DST, VA, ctx->mem_idx, MO_LE | MO_UW | MO_ALIGN); \
125 } while (0)
126 #define MEM_LOAD4s(DST, VA) \
127 do { \
128 CHECK_NOSHUF(VA, 4); \
129 - tcg_gen_qemu_ld_tl(DST, VA, ctx->mem_idx, MO_LE | MO_SL); \
129 + tcg_gen_qemu_ld_tl(DST, VA, ctx->mem_idx, MO_LE | MO_SL | MO_ALIGN); \
130 } while (0)
131 #define MEM_LOAD4u(DST, VA) \
132 do { \
133 CHECK_NOSHUF(VA, 4); \
134 - tcg_gen_qemu_ld_tl(DST, VA, ctx->mem_idx, MO_LE | MO_UL); \
134 + tcg_gen_qemu_ld_tl(DST, VA, ctx->mem_idx, MO_LE | MO_UL | MO_ALIGN); \
135 } while (0)
136 #define MEM_LOAD8u(DST, VA) \
137 do { \
138 CHECK_NOSHUF(VA, 8); \
139 - tcg_gen_qemu_ld_i64(DST, VA, ctx->mem_idx, MO_LE | MO_UQ); \
139 + tcg_gen_qemu_ld_i64(DST, VA, ctx->mem_idx, MO_LE | MO_UQ | MO_ALIGN); \
140 } while (0)
141
142 #define MEM_STORE1_FUNC(X) \
@@ -519,9 +519,15 @@ static inline TCGv gen_read_ireg(TCGv result, TCGv val, int shift)
519 #define fLOAD(NUM, SIZE, SIGN, EA, DST) MEM_LOAD##SIZE##SIGN(DST, EA)
520 #else
521 #define MEM_LOAD1 cpu_ldub_data_ra
522 -#define MEM_LOAD2 cpu_lduw_le_data_ra
523 -#define MEM_LOAD4 cpu_ldl_le_data_ra
524 -#define MEM_LOAD8 cpu_ldq_le_data_ra
522 +#define MEM_LOAD2(ENV, EA, RA) \
523 + cpu_ldw_mmu(ENV, EA, make_memop_idx(MO_LEUW | MO_ALIGN, \
524 + cpu_mmu_index(env_cpu(ENV), false)), RA)
525 +#define MEM_LOAD4(ENV, EA, RA) \
526 + cpu_ldl_mmu(ENV, EA, make_memop_idx(MO_LEUL | MO_ALIGN, \
527 + cpu_mmu_index(env_cpu(ENV), false)), RA)
528 +#define MEM_LOAD8(ENV, EA, RA) \
529 + cpu_ldq_mmu(ENV, EA, make_memop_idx(MO_LEUQ | MO_ALIGN, \
530 + cpu_mmu_index(env_cpu(ENV), false)), RA)
531
532 #define fLOAD(NUM, SIZE, SIGN, EA, DST) \
533 do { \