]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/ld: emit relocations for .debug_frame in external link mode
authorIan Lance Taylor <iant@golang.org>
Thu, 5 Sep 2013 19:55:21 +0000 (12:55 -0700)
committerIan Lance Taylor <iant@golang.org>
Thu, 5 Sep 2013 19:55:21 +0000 (12:55 -0700)
This should have been part of revision 16731:cdedb129e020, but
I missed it.  This fixes printing local variables when doing
an external link.

No test because we aren't doing any debug info testing yet.

Fixes #5719.

R=golang-dev, r
CC=golang-dev
https://golang.org/cl/13464046

src/cmd/ld/dwarf.c

index 32967d5f6bde8176afe35a5128b754d2de8d1d7e..c832bcc9441ded3fe358550e6784c30a0f9f6756 100644 (file)
@@ -39,6 +39,8 @@ static Sym*  infosym;
 static vlong infosympos;
 static vlong frameo;
 static vlong framesize;
+static Sym*  framesym;
+static vlong framesympos;
 static vlong pubnameso;
 static vlong pubnamessize;
 static vlong pubtypeso;
@@ -60,6 +62,10 @@ static Sym *linesec;
 static vlong linereloco;
 static vlong linerelocsize;
 
+static Sym *framesec;
+static vlong framereloco;
+static vlong framerelocsize;
+
 static char  gdbscript[1024];
 
 /*
@@ -1968,6 +1974,9 @@ writeframes(void)
        Sym *s;
        vlong fdeo, fdesize, pad, cfa, pc;
 
+       if(framesec == S)
+               framesec = lookup(".dwarfframe", 0);
+       framesec->nr = 0;
        frameo = cpos();
 
        // Emit the CIE, Section 6.4.1
@@ -2026,8 +2035,14 @@ writeframes(void)
                // Emit the FDE header for real, Section 6.4.1.
                cseek(fdeo);
                LPUT(fdesize);
-               LPUT(0);
-               addrput(p->pc);
+               if(linkmode == LinkExternal) {
+                       adddwarfrel(framesec, framesym, frameo, 4, 0);
+                       adddwarfrel(framesec, s, frameo, PtrSize, 0);
+               }
+               else {
+                       LPUT(0);
+                       addrput(p->pc);
+               }
                addrput(s->size);
                cseek(fdeo + 4 + fdesize);
        }
@@ -2360,6 +2375,10 @@ dwarfemitdebugsections(void)
        linereloco = writedwarfreloc(linesec);
        linerelocsize = cpos() - linereloco;
        align(linerelocsize);
+
+       framereloco = writedwarfreloc(framesec);
+       framerelocsize = cpos() - framereloco;
+       align(framerelocsize);
 }
 
 /*
@@ -2382,6 +2401,7 @@ enum
        ElfStrRelDebugInfo,
        ElfStrRelDebugAranges,
        ElfStrRelDebugLine,
+       ElfStrRelDebugFrame,
        NElfStrDbg
 };
 
@@ -2410,10 +2430,12 @@ dwarfaddshstrings(Sym *shstrtab)
                        elfstrdbg[ElfStrRelDebugInfo] = addstring(shstrtab, ".rela.debug_info");
                        elfstrdbg[ElfStrRelDebugAranges] = addstring(shstrtab, ".rela.debug_aranges");
                        elfstrdbg[ElfStrRelDebugLine] = addstring(shstrtab, ".rela.debug_line");
+                       elfstrdbg[ElfStrRelDebugFrame] = addstring(shstrtab, ".rela.debug_frame");
                } else {
                        elfstrdbg[ElfStrRelDebugInfo] = addstring(shstrtab, ".rel.debug_info");
                        elfstrdbg[ElfStrRelDebugAranges] = addstring(shstrtab, ".rel.debug_aranges");
                        elfstrdbg[ElfStrRelDebugLine] = addstring(shstrtab, ".rel.debug_line");
+                       elfstrdbg[ElfStrRelDebugFrame] = addstring(shstrtab, ".rel.debug_frame");
                }
 
                infosym = lookup(".debug_info", 0);
@@ -2424,6 +2446,9 @@ dwarfaddshstrings(Sym *shstrtab)
 
                linesym = lookup(".debug_line", 0);
                linesym->hide = 1;
+
+               framesym = lookup(".debug_frame", 0);
+               framesym->hide = 1;
        }
 }
 
@@ -2444,6 +2469,10 @@ dwarfaddelfsectionsyms()
                linesympos = cpos();
                putelfsectionsym(linesym, 0);
        }
+       if(framesym != nil) {
+               framesympos = cpos();
+               putelfsectionsym(framesym, 0);
+       }
 }
 
 static void
@@ -2469,7 +2498,7 @@ dwarfaddelfrelocheader(int elfstr, ElfShdr *shdata, vlong off, vlong size)
 void
 dwarfaddelfheaders(void)
 {
-       ElfShdr *sh, *shinfo, *sharanges, *shline;
+       ElfShdr *sh, *shinfo, *sharanges, *shline, *shframe;
 
        if(debug['w'])  // disable dwarf
                return;
@@ -2496,6 +2525,9 @@ dwarfaddelfheaders(void)
        sh->off = frameo;
        sh->size = framesize;
        sh->addralign = 1;
+       if(framesympos > 0)
+               putelfsymshndx(framesympos, sh->shnum);
+       shframe = sh;
 
        sh = newElfShdr(elfstrdbg[ElfStrDebugInfo]);
        sh->type = SHT_PROGBITS;
@@ -2548,6 +2580,9 @@ dwarfaddelfheaders(void)
 
        if(linerelocsize)
                dwarfaddelfrelocheader(ElfStrRelDebugLine, shline, linereloco, linerelocsize);
+
+       if(framerelocsize)
+               dwarfaddelfrelocheader(ElfStrRelDebugFrame, shframe, framereloco, framerelocsize);
 }
 
 /*