Skip to content

Commit dab04cf

Browse files
committed
Ensure stack is always aligned with 8 bytes
In dynamic linking mode, consider external functions may use data types such as 'long long int' or other equivalents. The program may encounter a Bus error if external functions access 8-byte data on the stack that is not properly aligned. To prevent the aforementioned issue, these changes adjust the Arm code generator to ensure that the program's stack is always aligned with 8 bytes. Since the RISC-V architecture does not yet support dynamic linking, the corresponding code generator is not modified in this commit.
1 parent 2043b9d commit dab04cf

File tree

2 files changed

+23
-10
lines changed

2 files changed

+23
-10
lines changed

src/arm-codegen.c

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -222,8 +222,9 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
222222
switch (ph2_ir->op) {
223223
case OP_define:
224224
emit(__sw(__AL, __lr, __sp, -4));
225-
emit(__movw(__AL, __r8, ph2_ir->src0 + 4));
226-
emit(__movt(__AL, __r8, ph2_ir->src0 + 4));
225+
ofs = ALIGN_UP(ph2_ir->src0 + 4, MIN_ALIGNMENT);
226+
emit(__movw(__AL, __r8, ofs));
227+
emit(__movt(__AL, __r8, ofs));
227228
emit(__sub_r(__AL, __sp, __sp, __r8));
228229
return;
229230
case OP_load_constant:
@@ -349,8 +350,9 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
349350
emit(__mov_r(__AL, __r0, __r0));
350351
else
351352
emit(__mov_r(__AL, __r0, rn));
352-
emit(__movw(__AL, __r8, ph2_ir->src1 + 4));
353-
emit(__movt(__AL, __r8, ph2_ir->src1 + 4));
353+
ofs = ALIGN_UP(ph2_ir->src1 + 4, MIN_ALIGNMENT);
354+
emit(__movw(__AL, __r8, ofs));
355+
emit(__movt(__AL, __r8, ofs));
354356
emit(__add_r(__AL, __sp, __sp, __r8));
355357
emit(__lw(__AL, __lr, __sp, -4));
356358
emit(__bx(__AL, __lr));
@@ -500,6 +502,8 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
500502
void plt_generate(void);
501503
void code_generate(void)
502504
{
505+
int ofs;
506+
503507
if (dynlink) {
504508
plt_generate();
505509
/* Call __libc_start_main() */
@@ -535,8 +539,9 @@ void code_generate(void)
535539
/* For both static and dynamic linking, we need to set up the stack
536540
* and call the main function.
537541
*/
538-
emit(__movw(__AL, __r8, GLOBAL_FUNC->stack_size));
539-
emit(__movt(__AL, __r8, GLOBAL_FUNC->stack_size));
542+
ofs = ALIGN_UP(GLOBAL_FUNC->stack_size, MIN_ALIGNMENT);
543+
emit(__movw(__AL, __r8, ofs));
544+
emit(__movt(__AL, __r8, ofs));
540545
emit(__sub_r(__AL, __sp, __sp, __r8));
541546
emit(__mov_r(__AL, __r12, __sp));
542547

@@ -547,8 +552,8 @@ void code_generate(void)
547552
56)); /* PC+8: skip exit (24) + syscall (36) + ret (4) - 8 */
548553

549554
/* exit - only for static linking */
550-
emit(__movw(__AL, __r8, GLOBAL_FUNC->stack_size));
551-
emit(__movt(__AL, __r8, GLOBAL_FUNC->stack_size));
555+
emit(__movw(__AL, __r8, ofs));
556+
emit(__movt(__AL, __r8, ofs));
552557
emit(__add_r(__AL, __sp, __sp, __r8));
553558
emit(__mov_r(__AL, __r0, __r0));
554559
emit(__mov_i(__AL, __r7, 1));
@@ -582,8 +587,8 @@ void code_generate(void)
582587
* will return to __libc_start_main. */
583588
emit(__b(__AL, MAIN_BB->elf_offset - elf_code->size));
584589
} else {
585-
emit(__movw(__AL, __r8, GLOBAL_FUNC->stack_size));
586-
emit(__movt(__AL, __r8, GLOBAL_FUNC->stack_size));
590+
emit(__movw(__AL, __r8, ofs));
591+
emit(__movt(__AL, __r8, ofs));
587592
emit(__add_r(__AL, __r8, __r12, __r8));
588593
emit(__lw(__AL, __r0, __r8, 0));
589594
emit(__add_i(__AL, __r1, __r8, 4));

src/defs.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,14 @@
9292
#define HOST_PTR_SIZE __SIZEOF_POINTER__
9393
#endif
9494

95+
#ifndef MIN_ALIGNMENT
96+
#define MIN_ALIGNMENT 8
97+
#endif
98+
99+
#ifndef ALIGN_UP
100+
#define ALIGN_UP(val, align) (((val) + (align) - 1) & ~((align) - 1))
101+
#endif
102+
95103
/* Common data structures */
96104
typedef struct arena_block {
97105
char *memory;

0 commit comments

Comments
 (0)