rebase to go1.8rc3
Resolves: BZ#1411242
This commit is contained in:
parent
0dbd49fdd7
commit
100fcef237
1
.gitignore
vendored
1
.gitignore
vendored
@ -37,3 +37,4 @@
|
||||
/go1.7.1.src.tar.gz
|
||||
/go1.7.3.src.tar.gz
|
||||
/go1.7.4.src.tar.gz
|
||||
/go1.8rc3.src.tar.gz
|
||||
|
@ -1,12 +0,0 @@
|
||||
diff -up go/src/runtime/runtime-gdb_test.go.gdb go/src/runtime/runtime-gdb_test.go
|
||||
--- go/src/runtime/runtime-gdb_test.go.gdb 2016-04-28 10:31:13.005689813 +0200
|
||||
+++ go/src/runtime/runtime-gdb_test.go 2016-04-28 10:32:12.202935125 +0200
|
||||
@@ -72,7 +72,7 @@ func main() {
|
||||
}
|
||||
`
|
||||
|
||||
-func TestGdbPython(t *testing.T) {
|
||||
+func testGdbPython(t *testing.T) {
|
||||
checkGdbEnvironment(t)
|
||||
checkGdbVersion(t)
|
||||
checkGdbPython(t)
|
@ -1,7 +1,7 @@
|
||||
diff -up go/src/cmd/dist/buildtool.go.bootstrap go/src/cmd/dist/buildtool.go
|
||||
--- go/src/cmd/dist/buildtool.go.bootstrap 2016-06-06 14:26:37.638374670 +0200
|
||||
+++ go/src/cmd/dist/buildtool.go 2016-06-06 14:30:33.873262307 +0200
|
||||
@@ -111,15 +111,23 @@ func bootstrapBuildTools() {
|
||||
--- go/src/cmd/dist/buildtool.go.bootstrap 2016-10-24 12:54:57.620563325 +0200
|
||||
+++ go/src/cmd/dist/buildtool.go 2016-10-24 13:12:25.036466602 +0200
|
||||
@@ -131,17 +131,25 @@ func bootstrapBuildTools() {
|
||||
defer os.Setenv("GOBIN", os.Getenv("GOBIN"))
|
||||
os.Setenv("GOBIN", "")
|
||||
|
||||
@ -21,15 +21,17 @@ diff -up go/src/cmd/dist/buildtool.go.bootstrap go/src/cmd/dist/buildtool.go
|
||||
// Run Go 1.4 to build binaries. Use -gcflags=-l to disable inlining to
|
||||
// workaround bugs in Go 1.4's compiler. See discussion thread:
|
||||
// https://groups.google.com/d/msg/golang-dev/Ss7mCKsvk8w/Gsq7VYI0AwAJ
|
||||
- run(workspace, ShowOutput|CheckExit, pathf("%s/bin/go", goroot_bootstrap), "install", "-gcflags=-l", "-v", "bootstrap/...")
|
||||
+ run(workspace, ShowOutput|CheckExit, bingopath, "install", "-gcflags=-l", "-v", "bootstrap/...")
|
||||
// Use the math_big_pure_go build tag to disable the assembly in math/big
|
||||
// which may contain unsupported instructions.
|
||||
- run(workspace, ShowOutput|CheckExit, pathf("%s/bin/go", goroot_bootstrap), "install", "-gcflags=-l", "-tags=math_big_pure_go", "-v", "bootstrap/cmd/...")
|
||||
+ run(workspace, ShowOutput|CheckExit, bingopath, "install", "-gcflags=-l", "-v", "-tags=math_big_pure_go", "bootstrap/...")
|
||||
|
||||
// Copy binaries into tool binary directory.
|
||||
for _, name := range bootstrapDirs {
|
||||
diff -up go/src/make.bash.bootstrap go/src/make.bash
|
||||
--- go/src/make.bash.bootstrap 2016-06-06 14:26:37.628374633 +0200
|
||||
+++ go/src/make.bash 2016-06-06 14:26:37.638374670 +0200
|
||||
@@ -118,8 +118,15 @@ echo '##### Building Go bootstrap tool.'
|
||||
--- go/src/make.bash.bootstrap 2016-10-24 12:54:57.606563267 +0200
|
||||
+++ go/src/make.bash 2016-10-24 12:54:57.620563325 +0200
|
||||
@@ -120,8 +120,15 @@ echo '##### Building Go bootstrap tool.'
|
||||
echo cmd/dist
|
||||
export GOROOT="$(cd .. && pwd)"
|
||||
GOROOT_BOOTSTRAP=${GOROOT_BOOTSTRAP:-$HOME/go1.4}
|
||||
@ -47,7 +49,7 @@ diff -up go/src/make.bash.bootstrap go/src/make.bash
|
||||
echo "Set \$GOROOT_BOOTSTRAP to a working Go tree >= Go 1.4." >&2
|
||||
exit 1
|
||||
fi
|
||||
@@ -128,8 +135,6 @@ if [ "$GOROOT_BOOTSTRAP" == "$GOROOT" ];
|
||||
@@ -130,8 +137,6 @@ if [ "$GOROOT_BOOTSTRAP" == "$GOROOT" ];
|
||||
echo "Set \$GOROOT_BOOTSTRAP to a working Go tree >= Go 1.4." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
31
golang.spec
31
golang.spec
@ -86,12 +86,12 @@
|
||||
%global gohostarch s390x
|
||||
%endif
|
||||
|
||||
%global go_api 1.7
|
||||
%global go_version 1.7.4
|
||||
%global go_api 1.8
|
||||
%global go_version 1.8rc3
|
||||
|
||||
Name: golang
|
||||
Version: 1.7.4
|
||||
Release: 2%{?dist}
|
||||
Version: 1.8
|
||||
Release: 0.rc3.1%{?dist}
|
||||
Summary: The Go Programming Language
|
||||
# source tree includes several copies of Mark.Twain-Tom.Sawyer.txt under Public Domain
|
||||
License: BSD and Public Domain
|
||||
@ -122,21 +122,10 @@ Patch0: golang-1.2-verbose-build.patch
|
||||
# use the arch dependent path in the bootstrap
|
||||
Patch212: golang-1.5-bootstrap-binary-path.patch
|
||||
|
||||
# disable TestGdbPython
|
||||
# https://github.com/golang/go/issues/11214
|
||||
Patch213: go1.5beta1-disable-TestGdbPython.patch
|
||||
|
||||
# we had been just removing the zoneinfo.zip, but that caused tests to fail for users that
|
||||
# later run `go test -a std`. This makes it only use the zoneinfo.zip where needed in tests.
|
||||
Patch215: ./go1.5-zoneinfo_testing_only.patch
|
||||
|
||||
#PPC64X relocation overflow fix
|
||||
Patch216: ppc64x-overflow-1.patch
|
||||
Patch217: ppc64x-overflow-2.patch
|
||||
|
||||
# Fix for https://github.com/golang/go/issues/17276
|
||||
Patch218: tzdata-fix.patch
|
||||
|
||||
# Proposed patch by mmunday https://golang.org/cl/35262
|
||||
Patch219: s390x-expose-IfInfomsg-X__ifi_pad.patch
|
||||
|
||||
@ -257,16 +246,8 @@ Summary: Golang shared object libraries
|
||||
# use the arch dependent path in the bootstrap
|
||||
%patch212 -p1 -b .bootstrap
|
||||
|
||||
# disable TestGdbPython
|
||||
%patch213 -p1 -b .gdb
|
||||
|
||||
%patch215 -p1
|
||||
|
||||
%patch216 -p1
|
||||
%patch217 -p1
|
||||
|
||||
%patch218 -p1
|
||||
|
||||
%patch219 -p1
|
||||
|
||||
%build
|
||||
@ -485,6 +466,10 @@ fi
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Fri Jan 27 2017 Jakub Čajka <jcajka@redhat.com> - 1.8-0.rc3.1
|
||||
- rebase to go1.8rc3
|
||||
- Resolves: BZ#1411242
|
||||
|
||||
* Fri Jan 20 2017 Jakub Čajka <jcajka@redhat.com> - 1.7.4-2
|
||||
- Resolves: BZ#1404679
|
||||
- expose IfInfomsg.X__ifi_pad on s390x
|
||||
|
@ -1,457 +0,0 @@
|
||||
From d6beea7f9ea1aa2ae5abca7fccb252767820aa13 Mon Sep 17 00:00:00 2001
|
||||
From: Lynn Boger <laboger@linux.vnet.ibm.com>
|
||||
Date: Tue, 26 Jul 2016 08:51:10 -0500
|
||||
Subject: [PATCH] cmd/link: split large elf text sections for ppc64x
|
||||
|
||||
Some applications built with Go on ppc64x with
|
||||
external linking can fail to link with relocation
|
||||
truncation errors, due to the way that the golang
|
||||
compiler generates a single go.o file containing
|
||||
a single large text section to send to the GNU
|
||||
linker. If the size of the single text section is
|
||||
greater than 2^26, this can lead to link errors
|
||||
due to 24 bit offset field in the bl (call)
|
||||
instruction.
|
||||
|
||||
This fix solves the problem by splitting into
|
||||
multiple text sections when this limit is reached.
|
||||
When this is done then the GNU linker can fix the
|
||||
long calls and insert jump tables where needed.
|
||||
---
|
||||
src/cmd/link/internal/ld/data.go | 52 +++++++++++++++++++++++++++++--
|
||||
src/cmd/link/internal/ld/elf.go | 60 ++++++++++++++++++++++++++++++++---
|
||||
src/cmd/link/internal/ld/lib.go | 20 ++++++++++++
|
||||
src/cmd/link/internal/ld/symtab.go | 64 ++++++++++++++++++++++++++++++++++++++
|
||||
src/cmd/link/internal/ppc64/asm.go | 12 ++++---
|
||||
src/runtime/symtab.go | 34 +++++++++++++++-----
|
||||
src/runtime/type.go | 16 +++++++++-
|
||||
7 files changed, 237 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go
|
||||
index 57a0dad..58ce18c 100644
|
||||
--- a/src/cmd/link/internal/ld/data.go
|
||||
+++ b/src/cmd/link/internal/ld/data.go
|
||||
@@ -527,7 +527,15 @@ func relocsym(s *LSym) {
|
||||
o = Symaddr(r.Sym) + r.Add - int64(r.Sym.Sect.Vaddr)
|
||||
|
||||
case obj.R_ADDROFF:
|
||||
- o = Symaddr(r.Sym) - int64(r.Sym.Sect.Vaddr) + r.Add
|
||||
+
|
||||
+ // The method offset tables using this relocation expect the offset to be relative
|
||||
+ // to the start of the first text section, even if there are multiple.
|
||||
+
|
||||
+ if Linkmode == LinkExternal && r.Sym.Sect.Name == ".text" && r.Sym.Sect.Vaddr != Segtext.Vaddr {
|
||||
+ o = Symaddr(r.Sym) - int64(Segtext.Vaddr) + r.Add
|
||||
+ } else {
|
||||
+ o = Symaddr(r.Sym) - int64(r.Sym.Sect.Vaddr) + r.Add
|
||||
+ }
|
||||
|
||||
// r->sym can be null when CALL $(constant) is transformed from absolute PC to relative PC call.
|
||||
case obj.R_CALL, obj.R_GOTPCREL, obj.R_PCREL:
|
||||
@@ -1926,6 +1934,7 @@ func textaddress() {
|
||||
}
|
||||
va := uint64(INITTEXT)
|
||||
sect.Vaddr = va
|
||||
+ n := 1
|
||||
for _, sym := range Ctxt.Textp {
|
||||
sym.Sect = sect
|
||||
if sym.Type&obj.SSUB != 0 {
|
||||
@@ -1948,9 +1957,30 @@ func textaddress() {
|
||||
} else {
|
||||
va += uint64(sym.Size)
|
||||
}
|
||||
+ // On ppc64x a text section should not be larger than 2^26 bytes due to the size of
|
||||
+ // call target offset field in the bl instruction. Splitting into text
|
||||
+ // sections smaller than this limit allows the GNU linker to modify the long calls
|
||||
+ // appropriately. The limit allows for the space for linker tables.
|
||||
+
|
||||
+ // Only break at outermost syms.
|
||||
+
|
||||
+ if sym.Outer == nil && Iself && Linkmode == LinkExternal && SysArch.InFamily(sys.PPC64) && va-sect.Vaddr > uint64(0x1c00000) {
|
||||
+
|
||||
+ // Set the length for the previous text section
|
||||
+ sect.Length = va - sect.Vaddr
|
||||
+
|
||||
+ // Create new section, set the starting Vaddr
|
||||
+ sect = addsection(&Segtext, ".text", 05)
|
||||
+ sect.Vaddr = va
|
||||
+
|
||||
+ // Create a symbol for the start and end of the secondary text section
|
||||
+ Linklookup(Ctxt, fmt.Sprintf("runtime.text.%d", n), 0).Sect = sect
|
||||
+ n++
|
||||
+ }
|
||||
}
|
||||
|
||||
sect.Length = va - sect.Vaddr
|
||||
+ Linklookup(Ctxt, "runtime.etext", 0).Sect = sect
|
||||
}
|
||||
|
||||
// assign addresses
|
||||
@@ -2057,11 +2087,27 @@ func address() {
|
||||
Segdwarf.Filelen = va - Segdwarf.Vaddr
|
||||
|
||||
text := Segtext.Sect
|
||||
+ lasttext := text
|
||||
var rodata *Section
|
||||
if Segrodata.Sect != nil {
|
||||
rodata = Segrodata.Sect
|
||||
} else {
|
||||
- rodata = text.Next
|
||||
+ // Could be multiple .text sections
|
||||
+ n := 1
|
||||
+ for sect := Segtext.Sect.Next; sect != nil; sect = sect.Next {
|
||||
+ if sect.Name != ".text" {
|
||||
+ break
|
||||
+ }
|
||||
+ lasttext = sect
|
||||
+ symname := fmt.Sprintf("runtime.text.%d", n)
|
||||
+ xdefine(symname, obj.STEXT, int64(sect.Vaddr))
|
||||
+ n++
|
||||
+ }
|
||||
+
|
||||
+ rodata = lasttext.Next
|
||||
+ if rodata != nil && rodata.Name != ".rodata" {
|
||||
+ Diag("Unexpected section order in text segment")
|
||||
+ }
|
||||
}
|
||||
var relrodata *Section
|
||||
typelink := rodata.Next
|
||||
@@ -2108,7 +2154,7 @@ func address() {
|
||||
}
|
||||
|
||||
xdefine("runtime.text", obj.STEXT, int64(text.Vaddr))
|
||||
- xdefine("runtime.etext", obj.STEXT, int64(text.Vaddr+text.Length))
|
||||
+ xdefine("runtime.etext", obj.STEXT, int64(lasttext.Vaddr+lasttext.Length))
|
||||
if HEADTYPE == obj.Hwindows {
|
||||
xdefine(".text", obj.STEXT, int64(text.Vaddr))
|
||||
}
|
||||
diff --git a/src/cmd/link/internal/ld/elf.go b/src/cmd/link/internal/ld/elf.go
|
||||
index 39d3609..ecb00c2 100644
|
||||
--- a/src/cmd/link/internal/ld/elf.go
|
||||
+++ b/src/cmd/link/internal/ld/elf.go
|
||||
@@ -1623,6 +1623,25 @@ func elfshname(name string) *ElfShdr {
|
||||
return nil
|
||||
}
|
||||
|
||||
+// Create an ElfShdr for the section with name.
|
||||
+// A new one is created even if one already exists with
|
||||
+// the same name.
|
||||
+func elfshnamedup(name string) *ElfShdr {
|
||||
+ var off int
|
||||
+ var sh *ElfShdr
|
||||
+
|
||||
+ for i := 0; i < nelfstr; i++ {
|
||||
+ if name == elfstr[i].s {
|
||||
+ off = elfstr[i].off
|
||||
+ sh = newElfShdr(int64(off))
|
||||
+ return sh
|
||||
+ }
|
||||
+ }
|
||||
+ Diag("cannot find elf name %s", name)
|
||||
+ errorexit()
|
||||
+ return nil
|
||||
+}
|
||||
+
|
||||
func elfshalloc(sect *Section) *ElfShdr {
|
||||
sh := elfshname(sect.Name)
|
||||
sect.Elfsect = sh
|
||||
@@ -1630,7 +1649,17 @@ func elfshalloc(sect *Section) *ElfShdr {
|
||||
}
|
||||
|
||||
func elfshbits(sect *Section) *ElfShdr {
|
||||
- sh := elfshalloc(sect)
|
||||
+ var sh *ElfShdr
|
||||
+
|
||||
+ if sect.Name == ".text" {
|
||||
+ if sect.Elfsect == nil {
|
||||
+ sect.Elfsect = elfshnamedup(sect.Name)
|
||||
+ }
|
||||
+ sh = sect.Elfsect
|
||||
+ } else {
|
||||
+ sh = elfshalloc(sect)
|
||||
+ }
|
||||
+
|
||||
// If this section has already been set up as a note, we assume type_ and
|
||||
// flags are already correct, but the other fields still need filling in.
|
||||
if sh.type_ == SHT_NOTE {
|
||||
@@ -1706,6 +1735,15 @@ func elfshreloc(sect *Section) *ElfShdr {
|
||||
}
|
||||
|
||||
sh := elfshname(elfRelType + sect.Name)
|
||||
+
|
||||
+ // There could be multiple text sections but each needs
|
||||
+ // its own .rela.text.
|
||||
+ if sect.Name == ".text" {
|
||||
+ if sh.info != 0 && sh.info != uint32(sect.Elfsect.shnum) {
|
||||
+ sh = elfshnamedup(elfRelType + sect.Name)
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
sh.type_ = uint32(typ)
|
||||
sh.entsize = uint64(SysArch.RegSize) * 2
|
||||
if typ == SHT_RELA {
|
||||
@@ -1776,9 +1814,12 @@ func Elfemitreloc() {
|
||||
Cput(0)
|
||||
}
|
||||
|
||||
- elfrelocsect(Segtext.Sect, Ctxt.Textp)
|
||||
- for sect := Segtext.Sect.Next; sect != nil; sect = sect.Next {
|
||||
- elfrelocsect(sect, datap)
|
||||
+ for sect := Segtext.Sect; sect != nil; sect = sect.Next {
|
||||
+ if sect.Name == ".text" {
|
||||
+ elfrelocsect(sect, Ctxt.Textp)
|
||||
+ } else {
|
||||
+ elfrelocsect(sect, datap)
|
||||
+ }
|
||||
}
|
||||
for sect := Segrodata.Sect; sect != nil; sect = sect.Next {
|
||||
elfrelocsect(sect, datap)
|
||||
@@ -2109,7 +2150,16 @@ func Asmbelfsetup() {
|
||||
elfshname("")
|
||||
|
||||
for sect := Segtext.Sect; sect != nil; sect = sect.Next {
|
||||
- elfshalloc(sect)
|
||||
+
|
||||
+ // There could be multiple .text sections. Instead check the Elfsect
|
||||
+ // field to determine if already has an ElfShdr and if not, create one.
|
||||
+ if sect.Name == ".text" {
|
||||
+ if sect.Elfsect == nil {
|
||||
+ sect.Elfsect = elfshnamedup(sect.Name)
|
||||
+ }
|
||||
+ } else {
|
||||
+ elfshalloc(sect)
|
||||
+ }
|
||||
}
|
||||
for sect := Segrodata.Sect; sect != nil; sect = sect.Next {
|
||||
elfshalloc(sect)
|
||||
diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go
|
||||
index 14f4fa9..709e7ca 100644
|
||||
--- a/src/cmd/link/internal/ld/lib.go
|
||||
+++ b/src/cmd/link/internal/ld/lib.go
|
||||
@@ -1956,6 +1956,26 @@ func genasmsym(put func(*LSym, string, int, int64, int64, int, *LSym)) {
|
||||
if s.Type == obj.STEXT {
|
||||
put(s, s.Name, 'T', s.Value, s.Size, int(s.Version), nil)
|
||||
}
|
||||
+ n := 0
|
||||
+
|
||||
+ // Generate base addresses for all text sections if there are multiple
|
||||
+ for sect := Segtext.Sect; sect != nil; sect = sect.Next {
|
||||
+ if n == 0 {
|
||||
+ n++
|
||||
+ continue
|
||||
+ }
|
||||
+ if sect.Name != ".text" {
|
||||
+ break
|
||||
+ }
|
||||
+ s = Linkrlookup(Ctxt, fmt.Sprintf("runtime.text.%d", n), 0)
|
||||
+ if s == nil {
|
||||
+ break
|
||||
+ }
|
||||
+ if s.Type == obj.STEXT {
|
||||
+ put(s, s.Name, 'T', s.Value, s.Size, int(s.Version), nil)
|
||||
+ }
|
||||
+ n++
|
||||
+ }
|
||||
s = Linklookup(Ctxt, "runtime.etext", 0)
|
||||
if s.Type == obj.STEXT {
|
||||
put(s, s.Name, 'T', s.Value, s.Size, int(s.Version), nil)
|
||||
diff --git a/src/cmd/link/internal/ld/symtab.go b/src/cmd/link/internal/ld/symtab.go
|
||||
index 06d7792..80eb33d 100644
|
||||
--- a/src/cmd/link/internal/ld/symtab.go
|
||||
+++ b/src/cmd/link/internal/ld/symtab.go
|
||||
@@ -315,6 +315,62 @@ func (libs byPkg) Swap(a, b int) {
|
||||
libs[a], libs[b] = libs[b], libs[a]
|
||||
}
|
||||
|
||||
+// Create a table with information on the text sections.
|
||||
+
|
||||
+func textsectionmap() uint32 {
|
||||
+
|
||||
+ t := Linklookup(Ctxt, "runtime.textsectionmap", 0)
|
||||
+ t.Type = obj.SRODATA
|
||||
+ t.Attr |= AttrReachable
|
||||
+ nsections := int64(0)
|
||||
+
|
||||
+ for sect := Segtext.Sect; sect != nil; sect = sect.Next {
|
||||
+ if sect.Name == ".text" {
|
||||
+ nsections++
|
||||
+ } else {
|
||||
+ break
|
||||
+ }
|
||||
+ }
|
||||
+ Symgrow(Ctxt, t, nsections*3*8)
|
||||
+
|
||||
+ off := int64(0)
|
||||
+ n := 0
|
||||
+
|
||||
+ // The vaddr for each text section is the difference between the section's
|
||||
+ // Vaddr and the Vaddr for the first text section as determined at compile
|
||||
+ // time.
|
||||
+
|
||||
+ // The symbol name for the start address of the first text section is
|
||||
+ // runtime.text. Additional text sections are named runtime.text.n where n is the
|
||||
+ // order of creation starting with 1. These symbols provide the section's
|
||||
+ // start address after relocation by the linker.
|
||||
+
|
||||
+ textbase := Segtext.Sect.Vaddr
|
||||
+ for sect := Segtext.Sect; sect != nil; sect = sect.Next {
|
||||
+ if sect.Name != ".text" {
|
||||
+ break
|
||||
+ }
|
||||
+ off = setuintxx(Ctxt, t, off, sect.Vaddr-textbase, int64(SysArch.IntSize))
|
||||
+ off = setuintxx(Ctxt, t, off, sect.Length, int64(SysArch.IntSize))
|
||||
+ if n == 0 {
|
||||
+ s := Linkrlookup(Ctxt, "runtime.text", 0)
|
||||
+ if s == nil {
|
||||
+ Diag("Unable to find symbol runtime.text\n")
|
||||
+ }
|
||||
+ off = setaddr(Ctxt, t, off, s)
|
||||
+
|
||||
+ } else {
|
||||
+ s := Linklookup(Ctxt, fmt.Sprintf("runtime.text.%d", n), 0)
|
||||
+ if s == nil {
|
||||
+ Diag("Unable to find symbol runtime.text.%d\n", n)
|
||||
+ }
|
||||
+ off = setaddr(Ctxt, t, off, s)
|
||||
+ }
|
||||
+ n++
|
||||
+ }
|
||||
+ return uint32(n)
|
||||
+}
|
||||
+
|
||||
func symtab() {
|
||||
dosymtype()
|
||||
|
||||
@@ -489,6 +545,8 @@ func symtab() {
|
||||
adduint(Ctxt, abihashgostr, uint64(hashsym.Size))
|
||||
}
|
||||
|
||||
+ nsections := textsectionmap()
|
||||
+
|
||||
// Information about the layout of the executable image for the
|
||||
// runtime to use. Any changes here must be matched by changes to
|
||||
// the definition of moduledata in runtime/symtab.go.
|
||||
@@ -527,6 +585,12 @@ func symtab() {
|
||||
Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.gcbss", 0))
|
||||
Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.types", 0))
|
||||
Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.etypes", 0))
|
||||
+
|
||||
+ // text section information
|
||||
+ Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.textsectionmap", 0))
|
||||
+ adduint(Ctxt, moduledata, uint64(nsections))
|
||||
+ adduint(Ctxt, moduledata, uint64(nsections))
|
||||
+
|
||||
// The typelinks slice
|
||||
Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.typelink", 0))
|
||||
adduint(Ctxt, moduledata, uint64(ntypelinks))
|
||||
diff --git a/src/cmd/link/internal/ppc64/asm.go b/src/cmd/link/internal/ppc64/asm.go
|
||||
index bd2e23f..ab59fa8 100644
|
||||
--- a/src/cmd/link/internal/ppc64/asm.go
|
||||
+++ b/src/cmd/link/internal/ppc64/asm.go
|
||||
@@ -813,12 +813,14 @@ func asmb() {
|
||||
ld.Asmbelfsetup()
|
||||
}
|
||||
|
||||
- sect := ld.Segtext.Sect
|
||||
- ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
|
||||
- ld.Codeblk(int64(sect.Vaddr), int64(sect.Length))
|
||||
- for sect = sect.Next; sect != nil; sect = sect.Next {
|
||||
+ for sect := ld.Segtext.Sect; sect != nil; sect = sect.Next {
|
||||
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
|
||||
- ld.Datblk(int64(sect.Vaddr), int64(sect.Length))
|
||||
+ // Might have multiple text sections
|
||||
+ if sect.Name == ".text" {
|
||||
+ ld.Codeblk(int64(sect.Vaddr), int64(sect.Length))
|
||||
+ } else {
|
||||
+ ld.Datblk(int64(sect.Vaddr), int64(sect.Length))
|
||||
+ }
|
||||
}
|
||||
|
||||
if ld.Segrodata.Filelen > 0 {
|
||||
diff --git a/src/runtime/symtab.go b/src/runtime/symtab.go
|
||||
index 4f6fae2..23e80ce 100644
|
||||
--- a/src/runtime/symtab.go
|
||||
+++ b/src/runtime/symtab.go
|
||||
@@ -195,8 +195,9 @@ type moduledata struct {
|
||||
end, gcdata, gcbss uintptr
|
||||
types, etypes uintptr
|
||||
|
||||
- typelinks []int32 // offsets from types
|
||||
- itablinks []*itab
|
||||
+ textsectmap []textsect
|
||||
+ typelinks []int32 // offsets from types
|
||||
+ itablinks []*itab
|
||||
|
||||
modulename string
|
||||
modulehashes []modulehash
|
||||
@@ -226,6 +227,14 @@ type functab struct {
|
||||
funcoff uintptr
|
||||
}
|
||||
|
||||
+// Mapping information for secondary text sections
|
||||
+
|
||||
+type textsect struct {
|
||||
+ vaddr uint64 // prelinked section vaddr
|
||||
+ length uint64 // section length
|
||||
+ baseaddr uintptr // relocated section address
|
||||
+}
|
||||
+
|
||||
const minfunc = 16 // minimum function size
|
||||
const pcbucketsize = 256 * minfunc // size of bucket in the pc->func lookup table
|
||||
|
||||
@@ -368,12 +377,23 @@ func findfunc(pc uintptr) *_func {
|
||||
ffb := (*findfuncbucket)(add(unsafe.Pointer(datap.findfunctab), b*unsafe.Sizeof(findfuncbucket{})))
|
||||
idx := ffb.idx + uint32(ffb.subbuckets[i])
|
||||
if pc < datap.ftab[idx].entry {
|
||||
- throw("findfunc: bad findfunctab entry")
|
||||
- }
|
||||
|
||||
- // linear search to find func with pc >= entry.
|
||||
- for datap.ftab[idx+1].entry <= pc {
|
||||
- idx++
|
||||
+ // If there are multiple text sections then the buckets for the secondary
|
||||
+ // text sections will be off because the addresses in those text sections
|
||||
+ // were relocated to higher addresses. Search back to find it.
|
||||
+
|
||||
+ for datap.ftab[idx].entry > pc && idx > 0 {
|
||||
+ idx--
|
||||
+ }
|
||||
+ if idx == 0 {
|
||||
+ throw("findfunc: bad findfunctab entry idx")
|
||||
+ }
|
||||
+ } else {
|
||||
+
|
||||
+ // linear search to find func with pc >= entry.
|
||||
+ for datap.ftab[idx+1].entry <= pc {
|
||||
+ idx++
|
||||
+ }
|
||||
}
|
||||
return (*_func)(unsafe.Pointer(&datap.pclntable[datap.ftab[idx].funcoff]))
|
||||
}
|
||||
diff --git a/src/runtime/type.go b/src/runtime/type.go
|
||||
index 5ef11a4..f641adc 100644
|
||||
--- a/src/runtime/type.go
|
||||
+++ b/src/runtime/type.go
|
||||
@@ -257,7 +257,21 @@ func (t *_type) textOff(off textOff) unsafe.Pointer {
|
||||
}
|
||||
return res
|
||||
}
|
||||
- res := md.text + uintptr(off)
|
||||
+ res := uintptr(0)
|
||||
+
|
||||
+ // Find the text section range that contains the offset to determine the section's base
|
||||
+ // address. In cases where there are multiple text sections, the base address might be
|
||||
+ // relocated by the linker.
|
||||
+
|
||||
+ for i := 0; i < len(md.textsectmap); i++ {
|
||||
+ sectaddr := md.textsectmap[i].vaddr
|
||||
+ sectlen := md.textsectmap[i].length
|
||||
+ if uint64(off) >= sectaddr && uint64(off) <= sectaddr+sectlen {
|
||||
+ res = md.textsectmap[i].baseaddr + uintptr(off) - uintptr(md.textsectmap[i].vaddr)
|
||||
+ break
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if res > md.etext {
|
||||
println("runtime: textOff", hex(off), "out of range", hex(md.text), "-", hex(md.etext))
|
||||
throw("runtime: text offset out of range")
|
@ -1,150 +0,0 @@
|
||||
From a5b97a846d70cd8db7f33c24f2b9159f935ce318 Mon Sep 17 00:00:00 2001
|
||||
From: Lynn Boger <laboger@linux.vnet.ibm.com>
|
||||
Date: Tue, 13 Sep 2016 15:13:08 -0500
|
||||
Subject: [PATCH] cmd/compile: large text sections on ppc64le
|
||||
|
||||
Additional fixes as submitted upstream.
|
||||
---
|
||||
src/cmd/link/internal/ld/data.go | 24 ++++++++++++------------
|
||||
src/cmd/link/internal/ld/lib.go | 2 +-
|
||||
src/cmd/link/internal/ld/symtab.go | 2 +-
|
||||
src/runtime/type.go | 28 ++++++++++++++++++----------
|
||||
4 files changed, 32 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go
|
||||
index 58ce18c..d8e43ff 100644
|
||||
--- a/src/cmd/link/internal/ld/data.go
|
||||
+++ b/src/cmd/link/internal/ld/data.go
|
||||
@@ -531,7 +531,7 @@ func relocsym(s *LSym) {
|
||||
// The method offset tables using this relocation expect the offset to be relative
|
||||
// to the start of the first text section, even if there are multiple.
|
||||
|
||||
- if Linkmode == LinkExternal && r.Sym.Sect.Name == ".text" && r.Sym.Sect.Vaddr != Segtext.Vaddr {
|
||||
+ if r.Sym.Sect.Name == ".text" {
|
||||
o = Symaddr(r.Sym) - int64(Segtext.Vaddr) + r.Add
|
||||
} else {
|
||||
o = Symaddr(r.Sym) - int64(r.Sym.Sect.Vaddr) + r.Add
|
||||
@@ -1928,7 +1928,6 @@ func textaddress() {
|
||||
|
||||
sect.Align = int32(Funcalign)
|
||||
Linklookup(Ctxt, "runtime.text", 0).Sect = sect
|
||||
- Linklookup(Ctxt, "runtime.etext", 0).Sect = sect
|
||||
if HEADTYPE == obj.Hwindows {
|
||||
Linklookup(Ctxt, ".text", 0).Sect = sect
|
||||
}
|
||||
@@ -1964,7 +1963,7 @@ func textaddress() {
|
||||
|
||||
// Only break at outermost syms.
|
||||
|
||||
- if sym.Outer == nil && Iself && Linkmode == LinkExternal && SysArch.InFamily(sys.PPC64) && va-sect.Vaddr > uint64(0x1c00000) {
|
||||
+ if sym.Outer == nil && Iself && Linkmode == LinkExternal && SysArch.InFamily(sys.PPC64) && va-sect.Vaddr > 0x1c00000 {
|
||||
|
||||
// Set the length for the previous text section
|
||||
sect.Length = va - sect.Vaddr
|
||||
@@ -1973,7 +1972,7 @@ func textaddress() {
|
||||
sect = addsection(&Segtext, ".text", 05)
|
||||
sect.Vaddr = va
|
||||
|
||||
- // Create a symbol for the start and end of the secondary text section
|
||||
+ // Create a symbol for the start of the secondary text section
|
||||
Linklookup(Ctxt, fmt.Sprintf("runtime.text.%d", n), 0).Sect = sect
|
||||
n++
|
||||
}
|
||||
@@ -2093,15 +2092,8 @@ func address() {
|
||||
rodata = Segrodata.Sect
|
||||
} else {
|
||||
// Could be multiple .text sections
|
||||
- n := 1
|
||||
- for sect := Segtext.Sect.Next; sect != nil; sect = sect.Next {
|
||||
- if sect.Name != ".text" {
|
||||
- break
|
||||
- }
|
||||
+ for sect := Segtext.Sect.Next; sect != nil && sect.Name == ".text"; sect = sect.Next {
|
||||
lasttext = sect
|
||||
- symname := fmt.Sprintf("runtime.text.%d", n)
|
||||
- xdefine(symname, obj.STEXT, int64(sect.Vaddr))
|
||||
- n++
|
||||
}
|
||||
|
||||
rodata = lasttext.Next
|
||||
@@ -2155,6 +2147,14 @@ func address() {
|
||||
|
||||
xdefine("runtime.text", obj.STEXT, int64(text.Vaddr))
|
||||
xdefine("runtime.etext", obj.STEXT, int64(lasttext.Vaddr+lasttext.Length))
|
||||
+
|
||||
+ n := 1
|
||||
+ for sect := Segtext.Sect.Next; sect != nil && sect.Name == ".text"; sect = sect.Next {
|
||||
+ symname := fmt.Sprintf("runtime.text.%d", n)
|
||||
+ xdefine(symname, obj.STEXT, int64(sect.Vaddr))
|
||||
+ n++
|
||||
+ }
|
||||
+
|
||||
if HEADTYPE == obj.Hwindows {
|
||||
xdefine(".text", obj.STEXT, int64(text.Vaddr))
|
||||
}
|
||||
diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go
|
||||
index 709e7ca..c37ef92 100644
|
||||
--- a/src/cmd/link/internal/ld/lib.go
|
||||
+++ b/src/cmd/link/internal/ld/lib.go
|
||||
@@ -1958,7 +1958,7 @@ func genasmsym(put func(*LSym, string, int, int64, int64, int, *LSym)) {
|
||||
}
|
||||
n := 0
|
||||
|
||||
- // Generate base addresses for all text sections if there are multiple
|
||||
+ // Generate base addresses for all text sections if there are multiple.
|
||||
for sect := Segtext.Sect; sect != nil; sect = sect.Next {
|
||||
if n == 0 {
|
||||
n++
|
||||
diff --git a/src/cmd/link/internal/ld/symtab.go b/src/cmd/link/internal/ld/symtab.go
|
||||
index 80eb33d..ec26f88 100644
|
||||
--- a/src/cmd/link/internal/ld/symtab.go
|
||||
+++ b/src/cmd/link/internal/ld/symtab.go
|
||||
@@ -331,7 +331,7 @@ func textsectionmap() uint32 {
|
||||
break
|
||||
}
|
||||
}
|
||||
- Symgrow(Ctxt, t, nsections*3*8)
|
||||
+ Symgrow(Ctxt, t, nsections*(2*int64(SysArch.IntSize)+int64(SysArch.PtrSize)))
|
||||
|
||||
off := int64(0)
|
||||
n := 0
|
||||
diff --git a/src/runtime/type.go b/src/runtime/type.go
|
||||
index f641adc..d4df5a9 100644
|
||||
--- a/src/runtime/type.go
|
||||
+++ b/src/runtime/type.go
|
||||
@@ -259,17 +259,25 @@ func (t *_type) textOff(off textOff) unsafe.Pointer {
|
||||
}
|
||||
res := uintptr(0)
|
||||
|
||||
- // Find the text section range that contains the offset to determine the section's base
|
||||
- // address. In cases where there are multiple text sections, the base address might be
|
||||
- // relocated by the linker.
|
||||
-
|
||||
- for i := 0; i < len(md.textsectmap); i++ {
|
||||
- sectaddr := md.textsectmap[i].vaddr
|
||||
- sectlen := md.textsectmap[i].length
|
||||
- if uint64(off) >= sectaddr && uint64(off) <= sectaddr+sectlen {
|
||||
- res = md.textsectmap[i].baseaddr + uintptr(off) - uintptr(md.textsectmap[i].vaddr)
|
||||
- break
|
||||
+ // The text, or instruction stream is generated as one large buffer. The off (offset) for a method is
|
||||
+ // its offset within this buffer. If the total text size gets too large, there can be issues on platforms like ppc64 if
|
||||
+ // the target of calls are too far for the call instruction. To resolve the large text issue, the text is split
|
||||
+ // into multiple text sections to allow the linker to generate long calls when necessary. When this happens, the vaddr
|
||||
+ // for each text section is set to its offset within the text. Each method's offset is compared against the section
|
||||
+ // vaddrs and sizes to determine the containing section. Then the section relative offset is added to the section's
|
||||
+ // relocated baseaddr to compute the method addess.
|
||||
+
|
||||
+ if len(md.textsectmap) > 1 {
|
||||
+ for i := 0; i < len(md.textsectmap); i++ {
|
||||
+ sectaddr := md.textsectmap[i].vaddr
|
||||
+ sectlen := md.textsectmap[i].length
|
||||
+ if uint64(off) >= sectaddr && uint64(off) <= sectaddr+sectlen {
|
||||
+ res = md.textsectmap[i].baseaddr + uintptr(off) - uintptr(md.textsectmap[i].vaddr)
|
||||
+ break
|
||||
+ }
|
||||
}
|
||||
+ } else {
|
||||
+ res = md.text + uintptr(off)
|
||||
}
|
||||
|
||||
if res > md.etext {
|
2
sources
2
sources
@ -1 +1 @@
|
||||
49c1076428a5d3b5ad7ac65233fcca2f go1.7.4.src.tar.gz
|
||||
SHA512 (go1.8rc3.src.tar.gz) = d15ab4347a2aef218f3295ddf8d45534e09036bf51cf81a6650a09e5556735953a34c9ee6b6848a44e1c5c945eecebf9c3a58748ecde688916b47e55e7f00c89
|
||||
|
@ -1,34 +0,0 @@
|
||||
From c5434f2973a87acff76bac359236e690d632ce95 Mon Sep 17 00:00:00 2001
|
||||
From: Alberto Donizetti <alb.donizetti@gmail.com>
|
||||
Date: Thu, 29 Sep 2016 13:59:10 +0200
|
||||
Subject: [PATCH] time: update test for tzdata-2016g
|
||||
|
||||
Fixes #17276
|
||||
|
||||
Change-Id: I0188cf9bc5fdb48c71ad929cc54206d03e0b96e4
|
||||
Reviewed-on: https://go-review.googlesource.com/29995
|
||||
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
|
||||
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
|
||||
TryBot-Result: Gobot Gobot <gobot@golang.org>
|
||||
---
|
||||
src/time/time_test.go | 7 +++++--
|
||||
1 file changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/time/time_test.go b/src/time/time_test.go
|
||||
index 68236fd..2e47d08 100644
|
||||
--- a/src/time/time_test.go
|
||||
+++ b/src/time/time_test.go
|
||||
@@ -943,8 +943,11 @@ func TestLoadFixed(t *testing.T) {
|
||||
// but Go and most other systems use "east is positive".
|
||||
// So GMT+1 corresponds to -3600 in the Go zone, not +3600.
|
||||
name, offset := Now().In(loc).Zone()
|
||||
- if name != "GMT+1" || offset != -1*60*60 {
|
||||
- t.Errorf("Now().In(loc).Zone() = %q, %d, want %q, %d", name, offset, "GMT+1", -1*60*60)
|
||||
+ // The zone abbreviation is "-01" since tzdata-2016g, and "GMT+1"
|
||||
+ // on earlier versions; we accept both. (Issue #17276).
|
||||
+ if !(name == "GMT+1" || name == "-01") || offset != -1*60*60 {
|
||||
+ t.Errorf("Now().In(loc).Zone() = %q, %d, want %q or %q, %d",
|
||||
+ name, offset, "GMT+1", "-01", -1*60*60)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user