diff options
author | Ian Lance Taylor <iant@golang.org> | 2013-09-05 12:55:21 -0700 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2013-09-05 12:55:21 -0700 |
commit | 4b9c0e9c2389474d300e6a5c82c01b68f5c04e53 (patch) | |
tree | 525d5fffa72835d0871b7f56d2ba25cf580a8184 | |
parent | 781c61f4631f85384087a6a4804da0b04937f07f (diff) | |
download | go-4b9c0e9c2389474d300e6a5c82c01b68f5c04e53.tar.gz |
cmd/ld: emit relocations for .debug_frame in external link mode
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 issue 5719.
R=golang-dev, r
CC=golang-dev
https://codereview.appspot.com/13464046
-rw-r--r-- | src/cmd/ld/dwarf.c | 41 |
1 files changed, 38 insertions, 3 deletions
diff --git a/src/cmd/ld/dwarf.c b/src/cmd/ld/dwarf.c index 32967d5f6..c832bcc94 100644 --- a/src/cmd/ld/dwarf.c +++ b/src/cmd/ld/dwarf.c @@ -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); } /* |