]> Cypherpunks repositories - gostls13.git/commitdiff
liblink: add leaf bit to object file format
authorRuss Cox <rsc@golang.org>
Wed, 16 Apr 2014 21:11:44 +0000 (17:11 -0400)
committerRuss Cox <rsc@golang.org>
Wed, 16 Apr 2014 21:11:44 +0000 (17:11 -0400)
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

src/cmd/ld/pcln.c
src/cmd/link/testdata/autosection.6
src/cmd/link/testdata/autoweak.6
src/cmd/link/testdata/dead.6
src/cmd/link/testdata/hello.6
src/cmd/link/testdata/layout.6
src/cmd/link/testdata/pclntab.6
src/liblink/objfile.c
src/pkg/debug/goobj/read.go

index bdb139f7a48f383f86ab64389c6f9d37c87e8636..b2370f2a91542cde5c119181e96c5098e6209e38 100644 (file)
@@ -112,7 +112,7 @@ pclntab(void)
 {
        int32 i, nfunc, start, funcstart;
        LSym *ftab, *s;
-       int32 off, end;
+       int32 off, end, frameptrsize;
        int64 funcdata_bytes;
        Pcln *pcln;
        Pciter it;
@@ -173,7 +173,10 @@ pclntab(void)
                // when a called function doesn't have argument information.
                // We need to make sure everything has argument information
                // 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) {
                        renumberfiles(pcln->file, pcln->nfile, &pcln->pcfile);
index 3a2e35a5b227ebca6093cb358a0762e802a51680..f392e416808f3a92e59faf51628911f57b0d4d1f 100644 (file)
Binary files a/src/cmd/link/testdata/autosection.6 and b/src/cmd/link/testdata/autosection.6 differ
index 1fd54ed7e60d52f1247958df3b85dadb9369d70f..a694e4729180ac7096dcbff6ef9393357b05e2b8 100644 (file)
Binary files a/src/cmd/link/testdata/autoweak.6 and b/src/cmd/link/testdata/autoweak.6 differ
index e0cdecea96b934cdb54ef1416a675cd3d4dca273..270416f0b6c6bc5ed628cdbab77cd7bdbdfb6d55 100644 (file)
Binary files a/src/cmd/link/testdata/dead.6 and b/src/cmd/link/testdata/dead.6 differ
index 9ec799b4f39e5c1f2944573a46c7f7a091cbe895..448d40f76b8ecf08d4b0418e17e66c055484e244 100644 (file)
Binary files a/src/cmd/link/testdata/hello.6 and b/src/cmd/link/testdata/hello.6 differ
index c5121ff154a5b12ba4f13ff087a3d8c37ef4f345..56d416a1a0a62316d4c47109bfbd111b6f91d4b0 100644 (file)
Binary files a/src/cmd/link/testdata/layout.6 and b/src/cmd/link/testdata/layout.6 differ
index 0f7ab6dd78b59ff505d186408427dc18c909d305..91583a3fd471460d06b111a20e87a41207c8ee79 100644 (file)
Binary files a/src/cmd/link/testdata/pclntab.6 and b/src/cmd/link/testdata/pclntab.6 differ
index b52b29ca59ebd55856f6340022e21c85f22e7d41..0c51e795f5582acdfe79cbdcb60265e593760c6b 100644 (file)
@@ -49,6 +49,7 @@
 //
 //     - args [int]
 //     - locals [int]
+//     - leaf [int]
 //     - nlocal [int]
 //     - local [nlocal automatics]
 //     - pcln [pcln table]
@@ -291,8 +292,11 @@ writesym(Link *ctxt, Biobuf *b, LSym *s)
                if(s->dupok)
                        Bprint(ctxt->bso, "dupok ");
                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);
+                       if(s->leaf)
+                               Bprint(ctxt->bso, " leaf");
+               }
                Bprint(ctxt->bso, "\n");
                for(p=s->text; p != nil; p = p->link)
                        Bprint(ctxt->bso, "\t%#06ux %P\n", (int)p->pc, p);
@@ -346,6 +350,7 @@ writesym(Link *ctxt, Biobuf *b, LSym *s)
        if(s->type == STEXT) {
                wrint(b, s->args);
                wrint(b, s->locals);
+               wrint(b, s->leaf);
                n = 0;
                for(a = s->autom; a != nil; a = a->link)
                        n++;
@@ -566,6 +571,7 @@ readsym(Link *ctxt, Biobuf *f, char *pkg, char *pn)
        if(s->type == STEXT) {
                s->args = rdint(f);
                s->locals = rdint(f);
+               s->leaf = rdint(f);
                n = rdint(f);
                for(i=0; i<n; i++) {
                        a = emallocz(sizeof *a);
index 8882eae53496e27aae41a72ea67b66d0e80b2485..c2e6fa09274f86516d52c584c8b9c6bf718b5dd3 100644 (file)
@@ -190,6 +190,7 @@ type Var struct {
 type Func struct {
        Args     int        // size in bytes of of argument frame: inputs and outputs
        Frame    int        // size in bytes of local variable frame
+       Leaf     bool       // function omits save of link register (ARM)
        Var      []Var      // detail about local variables
        PCSP     Data       // PC → SP offset map
        PCFile   Data       // PC → file number map (index into File)
@@ -621,6 +622,7 @@ func (r *objReader) parseObject(prefix []byte) error {
                        s.Func = f
                        f.Args = r.readInt()
                        f.Frame = r.readInt()
+                       f.Leaf = r.readInt() != 0
                        f.Var = make([]Var, r.readInt())
                        for i := range f.Var {
                                v := &f.Var[i]