Commit cc08d923 authored by Russ Cox's avatar Russ Cox

liblink: add leaf bit to object file format

Without the leaf bit, the linker cannot record
the correct frame size in the symbol table, and
then stack traces get mangled. (Only for ARM.)

Fixes #7338.
Fixes #7347.

LGTM=iant
R=iant
CC=golang-codereviews
https://golang.org/cl/88550043
parent 0de521d1
...@@ -112,7 +112,7 @@ pclntab(void) ...@@ -112,7 +112,7 @@ pclntab(void)
{ {
int32 i, nfunc, start, funcstart; int32 i, nfunc, start, funcstart;
LSym *ftab, *s; LSym *ftab, *s;
int32 off, end; int32 off, end, frameptrsize;
int64 funcdata_bytes; int64 funcdata_bytes;
Pcln *pcln; Pcln *pcln;
Pciter it; Pciter it;
...@@ -173,7 +173,10 @@ pclntab(void) ...@@ -173,7 +173,10 @@ pclntab(void)
// when a called function doesn't have argument information. // when a called function doesn't have argument information.
// We need to make sure everything has argument information // We need to make sure everything has argument information
// and then remove this. // and then remove this.
off = setuint32(ctxt, ftab, off, ctxt->cursym->locals + PtrSize); frameptrsize = PtrSize;
if(ctxt->cursym->leaf)
frameptrsize = 0;
off = setuint32(ctxt, ftab, off, ctxt->cursym->locals + frameptrsize);
if(pcln != &zpcln) { if(pcln != &zpcln) {
renumberfiles(pcln->file, pcln->nfile, &pcln->pcfile); renumberfiles(pcln->file, pcln->nfile, &pcln->pcfile);
......
...@@ -49,6 +49,7 @@ ...@@ -49,6 +49,7 @@
// //
// - args [int] // - args [int]
// - locals [int] // - locals [int]
// - leaf [int]
// - nlocal [int] // - nlocal [int]
// - local [nlocal automatics] // - local [nlocal automatics]
// - pcln [pcln table] // - pcln [pcln table]
...@@ -291,8 +292,11 @@ writesym(Link *ctxt, Biobuf *b, LSym *s) ...@@ -291,8 +292,11 @@ writesym(Link *ctxt, Biobuf *b, LSym *s)
if(s->dupok) if(s->dupok)
Bprint(ctxt->bso, "dupok "); Bprint(ctxt->bso, "dupok ");
Bprint(ctxt->bso, "size=%lld value=%lld", (vlong)s->size, (vlong)s->value); Bprint(ctxt->bso, "size=%lld value=%lld", (vlong)s->size, (vlong)s->value);
if(s->type == STEXT) if(s->type == STEXT) {
Bprint(ctxt->bso, " args=%#llux locals=%#llux", (uvlong)s->args, (uvlong)s->locals); Bprint(ctxt->bso, " args=%#llux locals=%#llux", (uvlong)s->args, (uvlong)s->locals);
if(s->leaf)
Bprint(ctxt->bso, " leaf");
}
Bprint(ctxt->bso, "\n"); Bprint(ctxt->bso, "\n");
for(p=s->text; p != nil; p = p->link) for(p=s->text; p != nil; p = p->link)
Bprint(ctxt->bso, "\t%#06ux %P\n", (int)p->pc, p); Bprint(ctxt->bso, "\t%#06ux %P\n", (int)p->pc, p);
...@@ -346,6 +350,7 @@ writesym(Link *ctxt, Biobuf *b, LSym *s) ...@@ -346,6 +350,7 @@ writesym(Link *ctxt, Biobuf *b, LSym *s)
if(s->type == STEXT) { if(s->type == STEXT) {
wrint(b, s->args); wrint(b, s->args);
wrint(b, s->locals); wrint(b, s->locals);
wrint(b, s->leaf);
n = 0; n = 0;
for(a = s->autom; a != nil; a = a->link) for(a = s->autom; a != nil; a = a->link)
n++; n++;
...@@ -566,6 +571,7 @@ readsym(Link *ctxt, Biobuf *f, char *pkg, char *pn) ...@@ -566,6 +571,7 @@ readsym(Link *ctxt, Biobuf *f, char *pkg, char *pn)
if(s->type == STEXT) { if(s->type == STEXT) {
s->args = rdint(f); s->args = rdint(f);
s->locals = rdint(f); s->locals = rdint(f);
s->leaf = rdint(f);
n = rdint(f); n = rdint(f);
for(i=0; i<n; i++) { for(i=0; i<n; i++) {
a = emallocz(sizeof *a); a = emallocz(sizeof *a);
......
...@@ -190,6 +190,7 @@ type Var struct { ...@@ -190,6 +190,7 @@ type Var struct {
type Func struct { type Func struct {
Args int // size in bytes of of argument frame: inputs and outputs Args int // size in bytes of of argument frame: inputs and outputs
Frame int // size in bytes of local variable frame Frame int // size in bytes of local variable frame
Leaf bool // function omits save of link register (ARM)
Var []Var // detail about local variables Var []Var // detail about local variables
PCSP Data // PC → SP offset map PCSP Data // PC → SP offset map
PCFile Data // PC → file number map (index into File) PCFile Data // PC → file number map (index into File)
...@@ -621,6 +622,7 @@ func (r *objReader) parseObject(prefix []byte) error { ...@@ -621,6 +622,7 @@ func (r *objReader) parseObject(prefix []byte) error {
s.Func = f s.Func = f
f.Args = r.readInt() f.Args = r.readInt()
f.Frame = r.readInt() f.Frame = r.readInt()
f.Leaf = r.readInt() != 0
f.Var = make([]Var, r.readInt()) f.Var = make([]Var, r.readInt())
for i := range f.Var { for i := range f.Var {
v := &f.Var[i] v := &f.Var[i]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment