qbe

Internal scc patchset buffer for QBE
Log | Files | Refs | README | LICENSE

commit ae8803cbe655f64a2ef1739c8dfc5c12af99bdfb
parent cd095a44db262351b09ea144a44b76e22d62c77a
Author: Michael Forney <mforney@mforney.org>
Date:   Sat, 25 Sep 2021 13:27:27 -0700

amd64: avoid reading past end of passed struct

If the size of the struct is not a multiple of 8, the actual struct
size may be different from the size reserved on the stack.

This fixes the case where the struct is passed in memory, but we
still may over-read a struct passed in registers. A TODO is added
for now.

Diffstat:
Mamd64/sysv.c | 10++++++++--
Marm64/abi.c | 1+
2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/amd64/sysv.c b/amd64/sysv.c @@ -4,6 +4,7 @@ typedef struct AClass AClass; typedef struct RAlloc RAlloc; struct AClass { + Typ *type; int inmem; int align; uint size; @@ -72,6 +73,7 @@ typclass(AClass *a, Typ *t) al = 8; sz = (sz + al-1) & -al; + a->type = t; a->size = sz; a->align = t->align; @@ -125,7 +127,7 @@ selret(Blk *b, Fn *fn) if (aret.inmem) { assert(rtype(fn->retr) == RTmp); emit(Ocopy, Kl, TMP(RAX), fn->retr, R); - blit(fn->retr, 0, r0, aret.size, fn); + blit(fn->retr, 0, r0, aret.type->size, fn); ca = 1; } else { ca = retr(reg, &aret); @@ -338,6 +340,10 @@ selcall(Fn *fn, Ins *i0, Ins *i1, RAlloc **rap) emit(Ocopy, Kl, i1->to, TMP(RAX), R); ca += 1; } else { + /* todo, may read out of bounds. + * gcc did this up until 5.2, but + * this should still be fixed. + */ if (aret.size > 8) { r = newtmp("abi", Kl, fn); aret.ref[1] = newtmp("abi", aret.cls[1], fn); @@ -407,7 +413,7 @@ selcall(Fn *fn, Ins *i0, Ins *i1, RAlloc **rap) if (i->op == Oargc) { if (a->align == 4) off += off & 15; - blit(r, off, i->arg[1], a->size, fn); + blit(r, off, i->arg[1], a->type->size, fn); } else { r1 = newtmp("abi", Kl, fn); emit(Ostorel, 0, R, i->arg[0], r1); diff --git a/arm64/abi.c b/arm64/abi.c @@ -144,6 +144,7 @@ sttmps(Ref tmp[], int cls[], uint nreg, Ref mem, Fn *fn) } } +/* todo, may read out of bounds */ static void ldregs(int reg[], int cls[], int n, Ref mem, Fn *fn) {