mirror of
git://c9x.me/qbe.git
synced 2026-04-05 18:09:47 +00:00
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.
This commit is contained in:
parent
0d68986b6f
commit
cd095a44db
@ -312,12 +312,14 @@ stkblob(Ref r, Class *c, Fn *fn, Insl **ilp)
|
|||||||
{
|
{
|
||||||
Insl *il;
|
Insl *il;
|
||||||
int al;
|
int al;
|
||||||
|
uint64_t sz;
|
||||||
|
|
||||||
il = alloc(sizeof *il);
|
il = alloc(sizeof *il);
|
||||||
al = c->t->align - 2; /* NAlign == 3 */
|
al = c->t->align - 2; /* NAlign == 3 */
|
||||||
if (al < 0)
|
if (al < 0)
|
||||||
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;
|
il->link = *ilp;
|
||||||
*ilp = il;
|
*ilp = il;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user