summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2013-09-05 12:55:21 -0700
committerIan Lance Taylor <iant@golang.org>2013-09-05 12:55:21 -0700
commit4b9c0e9c2389474d300e6a5c82c01b68f5c04e53 (patch)
tree525d5fffa72835d0871b7f56d2ba25cf580a8184 /src
parent781c61f4631f85384087a6a4804da0b04937f07f (diff)
downloadgo-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
Diffstat (limited to 'src')
-rw-r--r--src/cmd/ld/dwarf.c41
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);
}
/*