Allow lang/go to generate PT_TLS when cgo is used on OpenBSD. This makes

Go 1.6 pass regress on openbsd/386 and openbsd/amd64. Also stop exporting
environ and __progname from cgo, since these symbols are no longer required
by libc.
This commit is contained in:
jsing 2016-05-16 13:50:01 +00:00
parent 3388fc4cfd
commit 2f91d6db57
7 changed files with 424 additions and 14 deletions

View File

@ -1,4 +1,4 @@
# $OpenBSD: Makefile,v 1.32 2016/05/13 13:49:26 jsing Exp $
# $OpenBSD: Makefile,v 1.33 2016/05/16 13:50:01 jsing Exp $
ONLY_FOR_ARCHS = ${GO_ARCHS}
@ -8,7 +8,7 @@ VERSION = 1.6
EXTRACT_SUFX = .src.tar.gz
DISTNAME = go${VERSION}
PKGNAME = go-${VERSION}
REVISION = 1
REVISION = 2
CATEGORIES = lang
HOMEPAGE = https://golang.org/

View File

@ -0,0 +1,30 @@
$OpenBSD: patch-src_cmd_link_internal_ld_data_go,v 1.1 2016/05/16 13:50:02 jsing Exp $
--- src/cmd/link/internal/ld/data.go.orig Thu Feb 18 07:35:20 2016
+++ src/cmd/link/internal/ld/data.go Sat May 14 02:18:17 2016
@@ -385,7 +385,7 @@ func relocsym(s *LSym) {
case obj.R_TLS_LE:
isAndroidX86 := goos == "android" && (Thearch.Thechar == '6' || Thearch.Thechar == '8')
- if Linkmode == LinkExternal && Iself && HEADTYPE != obj.Hopenbsd && !isAndroidX86 {
+ if Linkmode == LinkExternal && Iself && !isAndroidX86 {
r.Done = 0
if r.Sym == nil {
r.Sym = Ctxt.Tlsg
@@ -419,7 +419,7 @@ func relocsym(s *LSym) {
case obj.R_TLS_IE:
isAndroidX86 := goos == "android" && (Thearch.Thechar == '6' || Thearch.Thechar == '8')
- if Linkmode == LinkExternal && Iself && HEADTYPE != obj.Hopenbsd && !isAndroidX86 {
+ if Linkmode == LinkExternal && Iself && !isAndroidX86 {
r.Done = 0
if r.Sym == nil {
r.Sym = Ctxt.Tlsg
@@ -1413,7 +1413,7 @@ func dodata() {
}
if s != nil && s.Type == obj.STLSBSS {
- if Iself && (Linkmode == LinkExternal || Debug['d'] == 0) && HEADTYPE != obj.Hopenbsd {
+ if Iself && (Linkmode == LinkExternal || Debug['d'] == 0) {
sect = addsection(&Segdata, ".tbss", 06)
sect.Align = int32(Thearch.Ptrsize)
sect.Vaddr = 0

View File

@ -1,14 +1,58 @@
$OpenBSD: patch-src_cmd_link_internal_ld_elf_go,v 1.1 2016/05/13 13:49:26 jsing Exp $
--- src/cmd/link/internal/ld/elf.go.orig Thu May 5 01:30:21 2016
+++ src/cmd/link/internal/ld/elf.go Thu May 5 01:30:47 2016
@@ -2585,8 +2585,8 @@ func Elfadddynsym(ctxt *Link, s *LSym) {
Addaddr(ctxt, d, s)
$OpenBSD: patch-src_cmd_link_internal_ld_elf_go,v 1.2 2016/05/16 13:50:02 jsing Exp $
--- src/cmd/link/internal/ld/elf.go.orig Sat May 14 02:17:19 2016
+++ src/cmd/link/internal/ld/elf.go Sat May 14 02:19:21 2016
@@ -1730,14 +1730,11 @@ func doelf() {
Addstring(shstrtab, ".bss")
Addstring(shstrtab, ".noptrbss")
- // generate .tbss section (except for OpenBSD where it's not supported)
- // for dynamic internal linker or external linking, so that various
- // binutils could correctly calculate PT_TLS size.
- // see https://golang.org/issue/5200.
- if HEADTYPE != obj.Hopenbsd {
- if Debug['d'] == 0 || Linkmode == LinkExternal {
- Addstring(shstrtab, ".tbss")
- }
+ // generate .tbss section for dynamic internal linker or external
+ // linking, so that various binutils could correctly calculate
+ // PT_TLS size - see https://golang.org/issue/5200.
+ if Debug['d'] == 0 || Linkmode == LinkExternal {
+ Addstring(shstrtab, ".tbss")
}
if HEADTYPE == obj.Hnetbsd {
Addstring(shstrtab, ".note.netbsd.ident")
@@ -2359,23 +2356,18 @@ func Asmbelf(symo int64) {
/*
* Thread-local storage segment (really just size).
*/
- // Do not emit PT_TLS for OpenBSD since ld.so(1) does
- // not currently support it. This is handled
- // appropriately in runtime/cgo.
- if HEADTYPE != obj.Hopenbsd {
- tlssize := uint64(0)
- for sect := Segdata.Sect; sect != nil; sect = sect.Next {
- if sect.Name == ".tbss" {
- tlssize = sect.Length
- }
+ tlssize := uint64(0)
+ for sect := Segdata.Sect; sect != nil; sect = sect.Next {
+ if sect.Name == ".tbss" {
+ tlssize = sect.Length
}
- if tlssize != 0 {
- ph := newElfPhdr()
- ph.type_ = PT_TLS
- ph.flags = PF_R
- ph.memsz = tlssize
- ph.align = uint64(Thearch.Regsize)
- }
+ }
+ if tlssize != 0 {
+ ph := newElfPhdr()
+ ph.type_ = PT_TLS
+ ph.flags = PF_R
+ ph.memsz = tlssize
+ ph.align = uint64(Thearch.Regsize)
}
}
- /* size */
- Adduint32(ctxt, d, 0)
+ /* size of object */
+ Adduint32(ctxt, d, uint32(s.Size))
/* type */
t := STB_GLOBAL << 4

View File

@ -0,0 +1,12 @@
$OpenBSD: patch-src_cmd_link_internal_ld_lib_go,v 1.1 2016/05/16 13:50:02 jsing Exp $
--- src/cmd/link/internal/ld/lib.go.orig Thu Feb 18 07:35:20 2016
+++ src/cmd/link/internal/ld/lib.go Sat May 14 02:17:32 2016
@@ -1951,7 +1951,7 @@ func genasmsym(put func(*LSym, string, int, int64, int
put(s, s.Extname, 'U', 0, 0, int(s.Version), nil)
case obj.STLSBSS:
- if Linkmode == LinkExternal && HEADTYPE != obj.Hopenbsd {
+ if Linkmode == LinkExternal {
put(s, s.Name, 't', Symaddr(s), s.Size, int(s.Version), s.Gotype)
}
}

View File

@ -0,0 +1,147 @@
$OpenBSD: patch-src_runtime_cgo_gcc_openbsd_386_c,v 1.1 2016/05/16 13:50:02 jsing Exp $
--- src/runtime/cgo/gcc_openbsd_386.c.orig Sat May 14 02:20:30 2016
+++ src/runtime/cgo/gcc_openbsd_386.c Sat May 14 02:20:56 2016
@@ -5,8 +5,6 @@
// +build cgo
#include <sys/types.h>
-#include <dlfcn.h>
-#include <errno.h>
#include <pthread.h>
#include <signal.h>
#include <string.h>
@@ -15,102 +13,6 @@
static void* threadentry(void*);
static void (*setg_gcc)(void*);
-// TCB_SIZE is sizeof(struct thread_control_block),
-// as defined in /usr/src/lib/librthread/tcb.h
-#define TCB_SIZE (4 * sizeof(void *))
-#define TLS_SIZE (2 * sizeof(void *))
-
-void *__get_tcb(void);
-void __set_tcb(void *);
-
-static int (*sys_pthread_create)(pthread_t *thread, const pthread_attr_t *attr,
- void *(*start_routine)(void *), void *arg);
-
-struct thread_args {
- void *(*func)(void *);
- void *arg;
-};
-
-static void
-tcb_fixup(int mainthread)
-{
- void *newtcb, *oldtcb;
-
- // The OpenBSD ld.so(1) does not currently support PT_TLS. As a result,
- // we need to allocate our own TLS space while preserving the existing
- // TCB that has been setup via librthread.
-
- newtcb = malloc(TCB_SIZE + TLS_SIZE);
- if(newtcb == NULL)
- abort();
-
- // The signal trampoline expects the TLS slots to be zeroed.
- bzero(newtcb, TLS_SIZE);
-
- oldtcb = __get_tcb();
- bcopy(oldtcb, newtcb + TLS_SIZE, TCB_SIZE);
- __set_tcb(newtcb + TLS_SIZE);
-
- // NOTE(jsing, minux): we can't free oldtcb without causing double-free
- // problem. so newtcb will be memory leaks. Get rid of this when OpenBSD
- // has proper support for PT_TLS.
-}
-
-static void *
-thread_start_wrapper(void *arg)
-{
- struct thread_args args = *(struct thread_args *)arg;
-
- free(arg);
- tcb_fixup(0);
-
- return args.func(args.arg);
-}
-
-static void init_pthread_wrapper(void) {
- void *handle;
-
- // Locate symbol for the system pthread_create function.
- handle = dlopen("libpthread.so", RTLD_LAZY);
- if(handle == NULL) {
- fprintf(stderr, "runtime/cgo: dlopen failed to load libpthread: %s\n", dlerror());
- abort();
- }
- sys_pthread_create = dlsym(handle, "pthread_create");
- if(sys_pthread_create == NULL) {
- fprintf(stderr, "runtime/cgo: dlsym failed to find pthread_create: %s\n", dlerror());
- abort();
- }
- dlclose(handle);
-}
-
-static pthread_once_t init_pthread_wrapper_once = PTHREAD_ONCE_INIT;
-
-int
-pthread_create(pthread_t *thread, const pthread_attr_t *attr,
- void *(*start_routine)(void *), void *arg)
-{
- struct thread_args *p;
-
- // we must initialize our wrapper in pthread_create, because it is valid to call
- // pthread_create in a static constructor, and in fact, our test for issue 9456
- // does just that.
- if(pthread_once(&init_pthread_wrapper_once, init_pthread_wrapper) != 0) {
- fprintf(stderr, "runtime/cgo: failed to initialize pthread_create wrapper\n");
- abort();
- }
-
- p = malloc(sizeof(*p));
- if(p == NULL) {
- errno = ENOMEM;
- return -1;
- }
- p->func = start_routine;
- p->arg = arg;
-
- return sys_pthread_create(thread, attr, thread_start_wrapper, p);
-}
-
void
x_cgo_init(G *g, void (*setg)(void*))
{
@@ -122,13 +24,6 @@ x_cgo_init(G *g, void (*setg)(void*))
pthread_attr_getstacksize(&attr, &size);
g->stacklo = (uintptr)&attr - size + 4096;
pthread_attr_destroy(&attr);
-
- if(pthread_once(&init_pthread_wrapper_once, init_pthread_wrapper) != 0) {
- fprintf(stderr, "runtime/cgo: failed to initialize pthread_create wrapper\n");
- abort();
- }
-
- tcb_fixup(1);
}
@@ -148,7 +43,7 @@ _cgo_sys_thread_start(ThreadStart *ts)
pthread_attr_getstacksize(&attr, &size);
// Leave stacklo=0 and set stackhi=size; mstack will do the rest.
ts->g->stackhi = size;
- err = sys_pthread_create(&p, &attr, threadentry, ts);
+ err = pthread_create(&p, &attr, threadentry, ts);
pthread_sigmask(SIG_SETMASK, &oset, nil);
@@ -162,8 +57,6 @@ static void*
threadentry(void *v)
{
ThreadStart ts;
-
- tcb_fixup(0);
ts = *(ThreadStart*)v;
free(v);

View File

@ -0,0 +1,147 @@
$OpenBSD: patch-src_runtime_cgo_gcc_openbsd_amd64_c,v 1.1 2016/05/16 13:50:02 jsing Exp $
--- src/runtime/cgo/gcc_openbsd_amd64.c.orig Thu Feb 18 07:35:22 2016
+++ src/runtime/cgo/gcc_openbsd_amd64.c Sat May 14 02:21:07 2016
@@ -5,8 +5,6 @@
// +build cgo
#include <sys/types.h>
-#include <dlfcn.h>
-#include <errno.h>
#include <pthread.h>
#include <signal.h>
#include <string.h>
@@ -15,102 +13,6 @@
static void* threadentry(void*);
static void (*setg_gcc)(void*);
-// TCB_SIZE is sizeof(struct thread_control_block),
-// as defined in /usr/src/lib/librthread/tcb.h
-#define TCB_SIZE (4 * sizeof(void *))
-#define TLS_SIZE (2 * sizeof(void *))
-
-void *__get_tcb(void);
-void __set_tcb(void *);
-
-static int (*sys_pthread_create)(pthread_t *thread, const pthread_attr_t *attr,
- void *(*start_routine)(void *), void *arg);
-
-struct thread_args {
- void *(*func)(void *);
- void *arg;
-};
-
-static void
-tcb_fixup(int mainthread)
-{
- void *newtcb, *oldtcb;
-
- // The OpenBSD ld.so(1) does not currently support PT_TLS. As a result,
- // we need to allocate our own TLS space while preserving the existing
- // TCB that has been setup via librthread.
-
- newtcb = malloc(TCB_SIZE + TLS_SIZE);
- if(newtcb == NULL)
- abort();
-
- // The signal trampoline expects the TLS slots to be zeroed.
- bzero(newtcb, TLS_SIZE);
-
- oldtcb = __get_tcb();
- bcopy(oldtcb, newtcb + TLS_SIZE, TCB_SIZE);
- __set_tcb(newtcb + TLS_SIZE);
-
- // NOTE(jsing, minux): we can't free oldtcb without causing double-free
- // problem. so newtcb will be memory leaks. Get rid of this when OpenBSD
- // has proper support for PT_TLS.
-}
-
-static void *
-thread_start_wrapper(void *arg)
-{
- struct thread_args args = *(struct thread_args *)arg;
-
- free(arg);
- tcb_fixup(0);
-
- return args.func(args.arg);
-}
-
-static void init_pthread_wrapper(void) {
- void *handle;
-
- // Locate symbol for the system pthread_create function.
- handle = dlopen("libpthread.so", RTLD_LAZY);
- if(handle == NULL) {
- fprintf(stderr, "runtime/cgo: dlopen failed to load libpthread: %s\n", dlerror());
- abort();
- }
- sys_pthread_create = dlsym(handle, "pthread_create");
- if(sys_pthread_create == NULL) {
- fprintf(stderr, "runtime/cgo: dlsym failed to find pthread_create: %s\n", dlerror());
- abort();
- }
- dlclose(handle);
-}
-
-static pthread_once_t init_pthread_wrapper_once = PTHREAD_ONCE_INIT;
-
-int
-pthread_create(pthread_t *thread, const pthread_attr_t *attr,
- void *(*start_routine)(void *), void *arg)
-{
- struct thread_args *p;
-
- // we must initialize our wrapper in pthread_create, because it is valid to call
- // pthread_create in a static constructor, and in fact, our test for issue 9456
- // does just that.
- if(pthread_once(&init_pthread_wrapper_once, init_pthread_wrapper) != 0) {
- fprintf(stderr, "runtime/cgo: failed to initialize pthread_create wrapper\n");
- abort();
- }
-
- p = malloc(sizeof(*p));
- if(p == NULL) {
- errno = ENOMEM;
- return -1;
- }
- p->func = start_routine;
- p->arg = arg;
-
- return sys_pthread_create(thread, attr, thread_start_wrapper, p);
-}
-
void
x_cgo_init(G *g, void (*setg)(void*))
{
@@ -122,13 +24,6 @@ x_cgo_init(G *g, void (*setg)(void*))
pthread_attr_getstacksize(&attr, &size);
g->stacklo = (uintptr)&attr - size + 4096;
pthread_attr_destroy(&attr);
-
- if(pthread_once(&init_pthread_wrapper_once, init_pthread_wrapper) != 0) {
- fprintf(stderr, "runtime/cgo: failed to initialize pthread_create wrapper\n");
- abort();
- }
-
- tcb_fixup(1);
}
@@ -149,7 +44,7 @@ _cgo_sys_thread_start(ThreadStart *ts)
// Leave stacklo=0 and set stackhi=size; mstack will do the rest.
ts->g->stackhi = size;
- err = sys_pthread_create(&p, &attr, threadentry, ts);
+ err = pthread_create(&p, &attr, threadentry, ts);
pthread_sigmask(SIG_SETMASK, &oset, nil);
@@ -163,8 +58,6 @@ static void*
threadentry(void *v)
{
ThreadStart ts;
-
- tcb_fixup(0);
ts = *(ThreadStart*)v;
free(v);

View File

@ -0,0 +1,30 @@
$OpenBSD: patch-src_runtime_cgo_openbsd_go,v 1.1 2016/05/16 13:50:02 jsing Exp $
--- src/runtime/cgo/openbsd.go.orig Thu Feb 18 07:35:22 2016
+++ src/runtime/cgo/openbsd.go Sat May 14 02:22:05 2016
@@ -8,24 +8,13 @@ package cgo
import _ "unsafe" // for go:linkname
-// Supply environ, __progname and __guard_local, because
-// we don't link against the standard OpenBSD crt0.o and
-// the libc dynamic library needs them.
+// Supply __guard_local because we don't link against the standard
+// OpenBSD crt0.o and the libc dynamic library needs it.
-//go:linkname _environ environ
-//go:linkname _progname __progname
//go:linkname _guard_local __guard_local
-var _environ uintptr
-var _progname uintptr
var _guard_local uintptr
-//go:cgo_export_dynamic environ environ
-//go:cgo_export_dynamic __progname __progname
-
// This is normally marked as hidden and placed in the
// .openbsd.randomdata section.
//go:cgo_export_dynamic __guard_local __guard_local
-
-// We override pthread_create to support PT_TLS.
-//go:cgo_export_dynamic pthread_create pthread_create