瀏覽代碼

fix for sloppy reg->mem in arm64 abi

Michael found a bug where some copies
from registers to memory in the arm64
abi clobber the stack. The test case
is:

    type :T = { w }
    function w $f() {
    @start
    	%p =:T call $g()
    	%x =w loadw %p
    	ret %x
    }

qbe will write 4 bytes out of bounds
when pulling the result struct from
its register. The same bug can be
observed if :T's definition is {w 3};
in this case qbe writes 16 bytes in
a slot of 12 bytes.

This patch changes stkblob() to use
the rounded argument size if it is
going to be restored from registers.

Relatedly, mem->reg loads for structs
with size < 16 and != 8, are treated
a bit sloppily both in the arm64 and
in the sysv abis. That is much less
harmful than the present bug.
Quentin Carbonneaux 4 年之前
父節點
當前提交
cd095a44db
共有 1 個文件被更改,包括 3 次插入1 次删除
  1. 3 1
      arm64/abi.c

+ 3 - 1
arm64/abi.c

@@ -312,12 +312,14 @@ stkblob(Ref r, Class *c, Fn *fn, Insl **ilp)
 {
 	Insl *il;
 	int al;
+	uint64_t sz;
 
 	il = alloc(sizeof *il);
 	al = c->t->align - 2; /* NAlign == 3 */
 	if (al < 0)
 		al = 0;
-	il->i = (Ins){Oalloc+al, Kl, r, {getcon(c->t->size, fn)}};
+	sz = c->class & Cptr ? c->t->size : c->size;
+	il->i = (Ins){Oalloc+al, Kl, r, {getcon(sz, fn)}};
 	il->link = *ilp;
 	*ilp = il;
 }