diff --git a/patches/alpine/README.txt b/patches/alpine/README.txt new file mode 100644 index 00000000..c1e86f19 --- /dev/null +++ b/patches/alpine/README.txt @@ -0,0 +1,6 @@ +All no-pic patches were based upon: +https://raw.githubusercontent.com/docker-library/golang/master/1.6/alpine/no-pic.patch +https://raw.githubusercontent.com/docker-library/golang/master/1.7/alpine/no-pic.patch + +no-pic-1.4.patch was hand-crafted from the above, based upon: +https://go.googlesource.com/go/+/go1.4.3/src/cmd/ld/lib.c diff --git a/patches/alpine/no-pic-go1.4.patch b/patches/alpine/no-pic-go1.4.patch new file mode 100644 index 00000000..8b99892d --- /dev/null +++ b/patches/alpine/no-pic-go1.4.patch @@ -0,0 +1,15 @@ +diff --git a/src/cmd/ld/lib.c b/src/cmd/ld/lib.c +--- a/src/cmd/ld/lib.c ++++ b/src/cmd/ld/lib.c +@@ -692,6 +692,11 @@ hostlink(void) { + p = strchr(p + 1, ' '); + } + ++ // The Go linker does not currently support building PIE ++ // executables when using the external linker. See: ++ // https://github.com/golang/go/issues/6940 ++ argv[argc++] = "-fno-PIC"; ++ + argv[argc] = nil; + + quotefmtinstall(); diff --git a/patches/alpine/no-pic-go1.5.patch b/patches/alpine/no-pic-go1.5.patch new file mode 100644 index 00000000..82ba80b1 --- /dev/null +++ b/patches/alpine/no-pic-go1.5.patch @@ -0,0 +1,15 @@ +diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go +--- a/src/cmd/link/internal/ld/lib.go ++++ b/src/cmd/link/internal/ld/lib.go +@@ -1071,6 +1071,11 @@ func hostlink() { + argv = append(argv, peimporteddlls()...) + } + ++ // The Go linker does not currently support building PIE ++ // executables when using the external linker. See: ++ // https://github.com/golang/go/issues/6940 ++ argv = append(argv, "-fno-PIC") ++ + if Debug['v'] != 0 { + fmt.Fprintf(&Bso, "host link:") + for _, v := range argv { diff --git a/patches/alpine/no-pic-go1.6.patch b/patches/alpine/no-pic-go1.6.patch new file mode 100644 index 00000000..db1f809d --- /dev/null +++ b/patches/alpine/no-pic-go1.6.patch @@ -0,0 +1,16 @@ +diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go +index 8ccbec9dd634..4e96bfadc260 100644 +--- a/src/cmd/link/internal/ld/lib.go ++++ b/src/cmd/link/internal/ld/lib.go +@@ -1194,6 +1194,11 @@ func hostlink() { + argv = append(argv, peimporteddlls()...) + } + ++ // The Go linker does not currently support building PIE ++ // executables when using the external linker. See: ++ // https://github.com/golang/go/issues/6940 ++ argv = append(argv, "-fno-PIC") ++ + if Debug['v'] != 0 { + fmt.Fprintf(&Bso, "host link:") + for _, v := range argv { diff --git a/patches/alpine/no-pic-go1.7.patch b/patches/alpine/no-pic-go1.7.patch new file mode 100644 index 00000000..b10f2905 --- /dev/null +++ b/patches/alpine/no-pic-go1.7.patch @@ -0,0 +1,16 @@ +diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go +index 14f4fa9..5599307 100644 +--- a/src/cmd/link/internal/ld/lib.go ++++ b/src/cmd/link/internal/ld/lib.go +@@ -1272,6 +1272,11 @@ func hostlink() { + argv = append(argv, peimporteddlls()...) + } + ++ // The Go linker does not currently support building PIE ++ // executables when using the external linker. See: ++ // https://github.com/golang/go/issues/6940 ++ argv = append(argv, "-fno-PIC") ++ + if Debug['v'] != 0 { + fmt.Fprintf(Bso, "host link:") + for _, v := range argv { diff --git a/patches/alpine/no-pic-go1.8.patch b/patches/alpine/no-pic-go1.8.patch new file mode 100644 index 00000000..b10f2905 --- /dev/null +++ b/patches/alpine/no-pic-go1.8.patch @@ -0,0 +1,16 @@ +diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go +index 14f4fa9..5599307 100644 +--- a/src/cmd/link/internal/ld/lib.go ++++ b/src/cmd/link/internal/ld/lib.go +@@ -1272,6 +1272,11 @@ func hostlink() { + argv = append(argv, peimporteddlls()...) + } + ++ // The Go linker does not currently support building PIE ++ // executables when using the external linker. See: ++ // https://github.com/golang/go/issues/6940 ++ argv = append(argv, "-fno-PIC") ++ + if Debug['v'] != 0 { + fmt.Fprintf(Bso, "host link:") + for _, v := range argv { diff --git a/patches/release-branch.go1.4.patch b/patches/release-branch.go1.4.patch new file mode 100644 index 00000000..941f3ee6 --- /dev/null +++ b/patches/release-branch.go1.4.patch @@ -0,0 +1,327 @@ +This was generated via: + + git clone https://go.googlesource.com/go archive/go + cd archive/go + git diff go1.4.3..origin/release-branch.go1.4 > + ../../patches/release-branch.go1.4.patch + +The branch tip was: 79d85a4965ea7c46db483314c3981751909d7883 +from October 14, 2016. + +The diff for the VERSION file was removed. + +This is most needed to build a bootstrap Go version 1.4.3 on macOS 10.12.1 per: +https://github.com/golang/go/issues/16352#issuecomment-255835099 +diff --git a/src/cmd/6l/asm.c b/src/cmd/6l/asm.c +index 18b5aa3119..2e9d339aef 100644 +--- a/src/cmd/6l/asm.c ++++ b/src/cmd/6l/asm.c +@@ -118,6 +118,8 @@ adddynrel(LSym *s, Reloc *r) + return; + + case 256 + R_X86_64_GOTPCREL: ++ case 256 + R_X86_64_GOTPCRELX: ++ case 256 + R_X86_64_REX_GOTPCRELX: + if(targ->type != SDYNIMPORT) { + // have symbol + if(r->off >= 2 && s->p[r->off-2] == 0x8b) { +diff --git a/src/cmd/8l/asm.c b/src/cmd/8l/asm.c +index 98c0424037..cff29488e8 100644 +--- a/src/cmd/8l/asm.c ++++ b/src/cmd/8l/asm.c +@@ -115,6 +115,7 @@ adddynrel(LSym *s, Reloc *r) + return; + + case 256 + R_386_GOT32: ++ case 256 + R_386_GOT32X: + if(targ->type != SDYNIMPORT) { + // have symbol + if(r->off >= 2 && s->p[r->off-2] == 0x8b) { +diff --git a/src/cmd/api/run.go b/src/cmd/api/run.go +index ed5613edd2..202106b805 100644 +--- a/src/cmd/api/run.go ++++ b/src/cmd/api/run.go +@@ -33,6 +33,10 @@ const goToolsVersion = "6698ca2900e2" + var goroot string + + func main() { ++ // Go 1.4 will never have new API, and the code below has bit-rotted. ++ fmt.Println("Skipping cmd/api checks") ++ return ++ + log.SetFlags(0) + goroot = os.Getenv("GOROOT") // should be set by run.{bash,bat} + if goroot == "" { +diff --git a/src/cmd/ld/elf.h b/src/cmd/ld/elf.h +index e84d996f25..e909a828d1 100644 +--- a/src/cmd/ld/elf.h ++++ b/src/cmd/ld/elf.h +@@ -502,8 +502,9 @@ typedef struct { + #define R_X86_64_DTPOFF32 21 /* Offset in TLS block */ + #define R_X86_64_GOTTPOFF 22 /* PC relative offset to IE GOT entry */ + #define R_X86_64_TPOFF32 23 /* Offset in static TLS block */ +- +-#define R_X86_64_COUNT 24 /* Count of defined relocation types. */ ++#define R_X86_64_GOTPCRELX 41 ++#define R_X86_64_REX_GOTPCRELX 42 ++#define R_X86_64_COUNT 26 /* Count of defined relocation types. */ + + + #define R_ALPHA_NONE 0 /* No reloc */ +@@ -612,8 +613,9 @@ typedef struct { + #define R_386_TLS_DTPMOD32 35 /* GOT entry containing TLS index */ + #define R_386_TLS_DTPOFF32 36 /* GOT entry containing TLS offset */ + #define R_386_TLS_TPOFF32 37 /* GOT entry of -ve static TLS offset */ ++#define R_386_GOT32X 43 + +-#define R_386_COUNT 38 /* Count of defined relocation types. */ ++#define R_386_COUNT 39 /* Count of defined relocation types. */ + + #define R_PPC_NONE 0 /* No relocation. */ + #define R_PPC_ADDR32 1 +diff --git a/src/cmd/ld/ldelf.c b/src/cmd/ld/ldelf.c +index dd5fa0d2a8..2e2fbd1737 100644 +--- a/src/cmd/ld/ldelf.c ++++ b/src/cmd/ld/ldelf.c +@@ -888,12 +888,15 @@ reltype(char *pn, int elftype, uchar *siz) + case R('6', R_X86_64_PC32): + case R('6', R_X86_64_PLT32): + case R('6', R_X86_64_GOTPCREL): ++ case R('6', R_X86_64_GOTPCRELX): ++ case R('6', R_X86_64_REX_GOTPCRELX): + case R('8', R_386_32): + case R('8', R_386_PC32): + case R('8', R_386_GOT32): + case R('8', R_386_PLT32): + case R('8', R_386_GOTOFF): + case R('8', R_386_GOTPC): ++ case R('8', R_386_GOT32X): + *siz = 4; + break; + case R('6', R_X86_64_64): +diff --git a/src/runtime/sys_darwin_386.s b/src/runtime/sys_darwin_386.s +index a961c71a83..3ae60eb8cc 100644 +--- a/src/runtime/sys_darwin_386.s ++++ b/src/runtime/sys_darwin_386.s +@@ -182,11 +182,17 @@ timeloop: + + systime: + // Fall back to system call (usually first call in this thread) +- LEAL 12(SP), AX // must be non-nil, unused ++ LEAL 16(SP), AX // must be non-nil, unused + MOVL AX, 4(SP) + MOVL $0, 8(SP) // time zone pointer ++ MOVL $0, 12(SP) // required as of Sierra; Issue 16570 + MOVL $116, AX + INT $0x80 ++ CMPL AX, $0 ++ JNE inreg ++ MOVL 16(SP), AX ++ MOVL 20(SP), DX ++inreg: + // sec is in AX, usec in DX + // convert to DX:AX nsec + MOVL DX, BX +diff --git a/src/runtime/sys_darwin_amd64.s b/src/runtime/sys_darwin_amd64.s +index bd397d72a7..fe9f38490f 100644 +--- a/src/runtime/sys_darwin_amd64.s ++++ b/src/runtime/sys_darwin_amd64.s +@@ -141,10 +141,16 @@ timeloop: + + systime: + // Fall back to system call (usually first call in this thread). +- MOVQ SP, DI // must be non-nil, unused ++ MOVQ SP, DI + MOVQ $0, SI ++ MOVQ $0, DX // required as of Sierra; Issue 16570 + MOVL $(0x2000000+116), AX + SYSCALL ++ CMPQ AX, $0 ++ JNE inreg ++ MOVQ 0(SP), AX ++ MOVL 8(SP), DX ++inreg: + // sec is in AX, usec in DX + // return nsec in AX + IMULQ $1000000000, AX +diff --git a/src/runtime/sys_linux_386.s b/src/runtime/sys_linux_386.s +index 0f6d4bbb5e..f9dec7597c 100644 +--- a/src/runtime/sys_linux_386.s ++++ b/src/runtime/sys_linux_386.s +@@ -379,9 +379,18 @@ TEXT runtime·sigaltstack(SB),NOSPLIT,$-8 + #define SEG_NOT_PRESENT 0x20 + #define USEABLE 0x40 + ++// `-1` means the kernel will pick a TLS entry on the first setldt call, ++// which happens during runtime init, and that we'll store back the saved ++// entry and reuse that on subsequent calls when creating new threads. ++DATA runtime·tls_entry_number+0(SB)/4, $-1 ++GLOBL runtime·tls_entry_number(SB), NOPTR, $4 ++ + // setldt(int entry, int address, int limit) ++// We use set_thread_area, which mucks with the GDT, instead of modify_ldt, ++// which would modify the LDT, but is disabled on some kernels. ++// The name, setldt, is a misnomer, although we leave this name as it is for ++// the compatibility with other platforms. + TEXT runtime·setldt(SB),NOSPLIT,$32 +- MOVL entry+0(FP), BX // entry + MOVL address+4(FP), CX // base address + + /* +@@ -400,18 +409,19 @@ TEXT runtime·setldt(SB),NOSPLIT,$32 + ADDL $0x8, CX // address + MOVL CX, 0(CX) + ++ // get entry number ++ MOVL runtime·tls_entry_number(SB), DX ++ + // set up user_desc + LEAL 16(SP), AX // struct user_desc +- MOVL BX, 0(AX) +- MOVL CX, 4(AX) +- MOVL $0xfffff, 8(AX) ++ MOVL DX, 0(AX) // unsigned int entry_number ++ MOVL CX, 4(AX) // unsigned long base_addr ++ MOVL $0xfffff, 8(AX) // unsigned int limit + MOVL $(SEG_32BIT|LIMIT_IN_PAGES|USEABLE|CONTENTS_DATA), 12(AX) // flag bits + +- // call modify_ldt +- MOVL $1, BX // func = 1 (write) +- MOVL AX, CX // user_desc +- MOVL $16, DX // sizeof(user_desc) +- MOVL $123, AX // syscall - modify_ldt ++ // call set_thread_area ++ MOVL AX, BX // user_desc ++ MOVL $243, AX // syscall - set_thread_area + CALL *runtime·_vdso(SB) + + // breakpoint on error +@@ -419,10 +429,18 @@ TEXT runtime·setldt(SB),NOSPLIT,$32 + JLS 2(PC) + INT $3 + +- // compute segment selector - (entry*8+7) +- MOVL entry+0(FP), AX ++ // read allocated entry number back out of user_desc ++ LEAL 16(SP), AX // get our user_desc back ++ MOVL 0(AX), AX ++ ++ // store entry number if the kernel allocated it ++ CMPL DX, $-1 ++ JNE 2(PC) ++ MOVL AX, runtime·tls_entry_number(SB) ++ ++ // compute segment selector - (entry*8+3) + SHLL $3, AX +- ADDL $7, AX ++ ADDL $3, AX + MOVW AX, GS + + RET +diff --git a/src/syscall/syscall_darwin_386.go b/src/syscall/syscall_darwin_386.go +index 2074e7ac2e..f75de000bd 100644 +--- a/src/syscall/syscall_darwin_386.go ++++ b/src/syscall/syscall_darwin_386.go +@@ -26,14 +26,21 @@ func NsecToTimeval(nsec int64) (tv Timeval) { + } + + //sysnb gettimeofday(tp *Timeval) (sec int32, usec int32, err error) +-func Gettimeofday(tv *Timeval) (err error) { +- // The tv passed to gettimeofday must be non-nil +- // but is otherwise unused. The answers come back +- // in the two registers. ++func Gettimeofday(tv *Timeval) error { ++ // The tv passed to gettimeofday must be non-nil. ++ // Before macOS Sierra (10.12), tv was otherwise unused and ++ // the answers came back in the two registers. ++ // As of Sierra, gettimeofday return zeros and populates ++ // tv itself. + sec, usec, err := gettimeofday(tv) +- tv.Sec = int32(sec) +- tv.Usec = int32(usec) +- return err ++ if err != nil { ++ return err ++ } ++ if sec != 0 || usec != 0 { ++ tv.Sec = int32(sec) ++ tv.Usec = int32(usec) ++ } ++ return nil + } + + func SetKevent(k *Kevent_t, fd, mode, flags int) { +diff --git a/src/syscall/syscall_darwin_amd64.go b/src/syscall/syscall_darwin_amd64.go +index 81b1fd3d2b..711d08d2ff 100644 +--- a/src/syscall/syscall_darwin_amd64.go ++++ b/src/syscall/syscall_darwin_amd64.go +@@ -26,14 +26,21 @@ func NsecToTimeval(nsec int64) (tv Timeval) { + } + + //sysnb gettimeofday(tp *Timeval) (sec int64, usec int32, err error) +-func Gettimeofday(tv *Timeval) (err error) { +- // The tv passed to gettimeofday must be non-nil +- // but is otherwise unused. The answers come back +- // in the two registers. ++func Gettimeofday(tv *Timeval) error { ++ // The tv passed to gettimeofday must be non-nil. ++ // Before macOS Sierra (10.12), tv was otherwise unused and ++ // the answers came back in the two registers. ++ // As of Sierra, gettimeofday return zeros and populates ++ // tv itself. + sec, usec, err := gettimeofday(tv) +- tv.Sec = sec +- tv.Usec = usec +- return err ++ if err != nil { ++ return err ++ } ++ if sec != 0 || usec != 0 { ++ tv.Sec = sec ++ tv.Usec = usec ++ } ++ return nil + } + + func SetKevent(k *Kevent_t, fd, mode, flags int) { +diff --git a/src/syscall/syscall_darwin_test.go b/src/syscall/syscall_darwin_test.go +new file mode 100644 +index 0000000000..dd0e32b968 +--- /dev/null ++++ b/src/syscall/syscall_darwin_test.go +@@ -0,0 +1,23 @@ ++// Copyright 2016 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++// +build darwin ++// +build amd64 386 ++ ++package syscall_test ++ ++import ( ++ "syscall" ++ "testing" ++) ++ ++func TestDarwinGettimeofday(t *testing.T) { ++ tv := &syscall.Timeval{} ++ if err := syscall.Gettimeofday(tv); err != nil { ++ t.Fatal(err) ++ } ++ if tv.Sec == 0 && tv.Usec == 0 { ++ t.Fatal("Sec and Usec both zero") ++ } ++} +diff --git a/src/time/time_test.go b/src/time/time_test.go +index 7e31dd78a9..b438817608 100644 +--- a/src/time/time_test.go ++++ b/src/time/time_test.go +@@ -915,6 +915,7 @@ func TestCountMallocs(t *testing.T) { + } + + func TestLoadFixed(t *testing.T) { ++ t.Skip("skipping test for Go 1.4; Issue 17545") + // Issue 4064: handle locations without any zone transitions. + loc, err := LoadLocation("Etc/GMT+1") + if err != nil { diff --git a/scripts/install b/scripts/install index 4397398c..58b7fc40 100755 --- a/scripts/install +++ b/scripts/install @@ -92,6 +92,31 @@ compile_go() { (rm -rf "$GO_INSTALL_ROOT" && display_fatal "Failed to compile. Check the logs at $GVM_ROOT/logs/go-$GO_NAME-compile.log") } +apply_patches() { + cd "$GO_INSTALL_ROOT/src" || + display_fatal "Couldn't cd into $GO_INSTALL_ROOT/src" + + minor_version="${VERSION:0:5}" + patch_dir="$GVM_ROOT/patches" + patches=() + + release_branch_patch="${patch_dir}/release-branch.${minor_version}.patch" + if [ -f "$release_branch_patch" ]; then + patches+=("$release_branch_patch") + fi + if [ -f "/etc/apk/repositories" ]; then + patches+=("${patch_dir}/alpine/no-pic-${minor_version}.patch") + fi + + for patch_file in "${patches[@]}"; do + display_message "Applying $patch_file..." + if ! patch -p2 <"$patch_file"; then + display_error "Failed to apply $patch_file" + return + fi + done +} + create_enviroment() { new_env_file=$GVM_ROOT/environments/$GO_NAME echo "export GVM_ROOT; GVM_ROOT=\"$GVM_ROOT\"" > "$new_env_file" @@ -145,6 +170,7 @@ install_go() { create_global_package_set copy_source + apply_patches compile_go create_enviroment