Commit fd392ee5 authored by Shenghou Ma's avatar Shenghou Ma Committed by Minux Ma

cmd/internal/ld: generate correct .debug_frames on RISC architectures

With this patch, gdb seems to be able to corretly backtrace Go
process on at least linux/{arm,arm64,ppc64}.

Change-Id: Ic40a2a70e71a19c4a92e4655710f38a807b67e9a
Reviewed-on: https://go-review.googlesource.com/9822
Run-TryBot: Minux Ma <minux@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
parent a3dfcf51
......@@ -72,7 +72,8 @@ const (
MINLC = 4
)
/* Used by ../ld/dwarf.c */
/* Used by ../internal/ld/dwarf.go */
const (
DWARFREGSP = 13
DWARFREGLR = 14
)
......@@ -56,6 +56,7 @@ func linkarchinit() {
ld.Thearch.Maxalign = MaxAlign
ld.Thearch.Minlc = MINLC
ld.Thearch.Dwarfregsp = DWARFREGSP
ld.Thearch.Dwarfreglr = DWARFREGLR
ld.Thearch.Adddynlib = adddynlib
ld.Thearch.Adddynrel = adddynrel
......
......@@ -40,7 +40,8 @@ const (
MINLC = 1
)
/* Used by ../ld/dwarf.c */
/* Used by ../internal/ld/dwarf.go */
const (
DWARFREGSP = 7
DWARFREGLR = 16
)
......@@ -59,6 +59,7 @@ func linkarchinit() {
ld.Thearch.Maxalign = MaxAlign
ld.Thearch.Minlc = MINLC
ld.Thearch.Dwarfregsp = DWARFREGSP
ld.Thearch.Dwarfreglr = DWARFREGLR
ld.Thearch.Adddynlib = adddynlib
ld.Thearch.Adddynrel = adddynrel
......
......@@ -71,7 +71,8 @@ const (
MINLC = 4
)
/* Used by ../ld/dwarf.c */
/* Used by ../internal/ld/dwarf.go */
const (
DWARFREGSP = 31
DWARFREGLR = 30
)
......@@ -56,6 +56,7 @@ func linkarchinit() {
ld.Thearch.Maxalign = MaxAlign
ld.Thearch.Minlc = MINLC
ld.Thearch.Dwarfregsp = DWARFREGSP
ld.Thearch.Dwarfreglr = DWARFREGLR
ld.Thearch.Adddynlib = adddynlib
ld.Thearch.Adddynrel = adddynrel
......
......@@ -40,7 +40,8 @@ const (
MINLC = 1
)
/* Used by ../ld/dwarf.c */
/* Used by ../internal/ld/dwarf.go */
const (
DWARFREGSP = 4
DWARFREGLR = 8
)
......@@ -56,6 +56,7 @@ func linkarchinit() {
ld.Thearch.Maxalign = MaxAlign
ld.Thearch.Minlc = MINLC
ld.Thearch.Dwarfregsp = DWARFREGSP
ld.Thearch.Dwarfreglr = DWARFREGLR
ld.Thearch.Adddynlib = adddynlib
ld.Thearch.Adddynrel = adddynrel
......
......@@ -71,7 +71,8 @@ const (
MINLC = 4
)
/* Used by ../ld/dwarf.c */
/* Used by ../internal/ld/dwarf.go */
const (
DWARFREGSP = 1
DWARFREGLR = 65
)
......@@ -60,6 +60,7 @@ func linkarchinit() {
ld.Thearch.Maxalign = MaxAlign
ld.Thearch.Minlc = MINLC
ld.Thearch.Dwarfregsp = DWARFREGSP
ld.Thearch.Dwarfreglr = DWARFREGLR
ld.Thearch.Adddynlib = adddynlib
ld.Thearch.Adddynrel = adddynrel
......
......@@ -1692,11 +1692,17 @@ func writelines() {
switch a.Name {
case obj.A_AUTO:
dt = DW_ABRV_AUTO
offs = int64(a.Aoffset) - int64(Thearch.Ptrsize)
offs = int64(a.Aoffset)
if !haslinkregister() {
offs -= int64(Thearch.Ptrsize)
}
case obj.A_PARAM:
dt = DW_ABRV_PARAM
offs = int64(a.Aoffset)
if haslinkregister() {
offs += int64(Thearch.Ptrsize)
}
default:
continue
......@@ -1749,7 +1755,6 @@ func writelines() {
const (
CIERESERVE = 16
DATAALIGNMENTFACTOR = -4
FAKERETURNCOLUMN = 16 // TODO gdb6 doesn't like > 15?
)
func putpccfadelta(deltapc int64, cfa int64) {
......@@ -1778,21 +1783,30 @@ func writeframes() {
frameo = Cpos()
// Emit the CIE, Section 6.4.1
Thearch.Lput(CIERESERVE) // initial length, must be multiple of thearch.ptrsize
Thearch.Lput(0xffffffff) // cid.
Cput(3) // dwarf version (appendix F)
Cput(0) // augmentation ""
uleb128put(1) // code_alignment_factor
sleb128put(DATAALIGNMENTFACTOR) // guess
uleb128put(FAKERETURNCOLUMN) // return_address_register
Thearch.Lput(CIERESERVE) // initial length, must be multiple of thearch.ptrsize
Thearch.Lput(0xffffffff) // cid.
Cput(3) // dwarf version (appendix F)
Cput(0) // augmentation ""
uleb128put(1) // code_alignment_factor
sleb128put(DATAALIGNMENTFACTOR) // guess
uleb128put(int64(Thearch.Dwarfreglr)) // return_address_register
Cput(DW_CFA_def_cfa)
uleb128put(int64(Thearch.Dwarfregsp)) // register SP (**ABI-dependent, defined in l.h)
uleb128put(int64(Thearch.Ptrsize)) // offset
if haslinkregister() {
uleb128put(int64(0)) // offset
} else {
uleb128put(int64(Thearch.Ptrsize)) // offset
}
Cput(DW_CFA_offset + FAKERETURNCOLUMN) // return address
uleb128put(int64(-Thearch.Ptrsize) / DATAALIGNMENTFACTOR) // at cfa - x*4
Cput(DW_CFA_offset_extended)
uleb128put(int64(Thearch.Dwarfreglr)) // return address
if haslinkregister() {
uleb128put(int64(0) / DATAALIGNMENTFACTOR) // at cfa - 0
} else {
uleb128put(int64(-Thearch.Ptrsize) / DATAALIGNMENTFACTOR) // at cfa - x*4
}
// 4 is to exclude the length field.
pad := CIERESERVE + frameo + 4 - Cpos()
......@@ -1834,7 +1848,11 @@ func writeframes() {
}
}
putpccfadelta(int64(nextpc)-int64(pcsp.pc), int64(Thearch.Ptrsize)+int64(pcsp.value))
if haslinkregister() {
putpccfadelta(int64(nextpc)-int64(pcsp.pc), int64(pcsp.value))
} else {
putpccfadelta(int64(nextpc)-int64(pcsp.pc), int64(Thearch.Ptrsize)+int64(pcsp.value))
}
}
fdesize = Cpos() - fdeo - 4 // exclude the length field.
......
......@@ -86,6 +86,7 @@ type Arch struct {
Maxalign int
Minlc int
Dwarfregsp int
Dwarfreglr int
Linuxdynld string
Freebsddynld string
Netbsddynld string
......
......@@ -85,7 +85,7 @@ func TestGdbPython(t *testing.T) {
// stack frames on RISC architectures.
canBackTrace := false
switch runtime.GOARCH {
case "amd64", "386":
case "amd64", "386", "ppc64", "ppc64le", "arm", "arm64":
canBackTrace = true
args = append(args,
"-ex", "echo BEGIN goroutine 2 bt\n",
......
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