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 { \