Commit 8a9f2a6b by Ian Lance Taylor

compiler, runtime: harmonize types referenced by both C and Go

    
    Compiling with LTO revealed a number of cases in the runtime and
    standard library where C and Go disagreed about the type of an object or
    function (or where Go and code generated by the compiler disagreed). In
    all cases the underlying representation was the same (e.g., uintptr vs.
    void*), so this wasn't causing actual problems, but it did result in a
    number of annoying warnings when compiling with LTO.
    
    Reviewed-on: https://go-review.googlesource.com/c/160700

From-SVN: r268923
parent c8530c41
4a6f2bb2c8d3f00966f001a5b03c57cb4a278265 03e28273a4fcb114f5204d52ed107591404002f4
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the gofrontend repository. merge done from the gofrontend repository.
...@@ -1344,7 +1344,7 @@ Func_descriptor_expression::make_func_descriptor_type() ...@@ -1344,7 +1344,7 @@ Func_descriptor_expression::make_func_descriptor_type()
if (Func_descriptor_expression::descriptor_type != NULL) if (Func_descriptor_expression::descriptor_type != NULL)
return; return;
Type* uintptr_type = Type::lookup_integer_type("uintptr"); Type* uintptr_type = Type::lookup_integer_type("uintptr");
Type* struct_type = Type::make_builtin_struct_type(1, "code", uintptr_type); Type* struct_type = Type::make_builtin_struct_type(1, "fn", uintptr_type);
Func_descriptor_expression::descriptor_type = Func_descriptor_expression::descriptor_type =
Type::make_builtin_named_type("functionDescriptor", struct_type); Type::make_builtin_named_type("functionDescriptor", struct_type);
} }
...@@ -3874,7 +3874,9 @@ Unsafe_type_conversion_expression::do_get_backend(Translate_context* context) ...@@ -3874,7 +3874,9 @@ Unsafe_type_conversion_expression::do_get_backend(Translate_context* context)
|| et->integer_type() != NULL || et->integer_type() != NULL
|| et->is_nil_type()); || et->is_nil_type());
else if (et->is_unsafe_pointer_type()) else if (et->is_unsafe_pointer_type())
go_assert(t->points_to() != NULL); go_assert(t->points_to() != NULL
|| (t->integer_type() != NULL
&& t->integer_type() == Type::lookup_integer_type("uintptr")->real_type()));
else if (t->interface_type() != NULL) else if (t->interface_type() != NULL)
{ {
bool empty_iface = t->interface_type()->is_empty(); bool empty_iface = t->interface_type()->is_empty();
......
...@@ -4513,13 +4513,13 @@ Build_recover_thunks::can_recover_arg(Location location) ...@@ -4513,13 +4513,13 @@ Build_recover_thunks::can_recover_arg(Location location)
builtin_return_address = builtin_return_address =
Gogo::declare_builtin_rf_address("__builtin_return_address"); Gogo::declare_builtin_rf_address("__builtin_return_address");
Type* uintptr_type = Type::lookup_integer_type("uintptr");
static Named_object* can_recover; static Named_object* can_recover;
if (can_recover == NULL) if (can_recover == NULL)
{ {
const Location bloc = Linemap::predeclared_location(); const Location bloc = Linemap::predeclared_location();
Typed_identifier_list* param_types = new Typed_identifier_list(); Typed_identifier_list* param_types = new Typed_identifier_list();
Type* voidptr_type = Type::make_pointer_type(Type::make_void_type()); param_types->push_back(Typed_identifier("a", uintptr_type, bloc));
param_types->push_back(Typed_identifier("a", voidptr_type, bloc));
Type* boolean_type = Type::lookup_bool_type(); Type* boolean_type = Type::lookup_bool_type();
Typed_identifier_list* results = new Typed_identifier_list(); Typed_identifier_list* results = new Typed_identifier_list();
results->push_back(Typed_identifier("", boolean_type, bloc)); results->push_back(Typed_identifier("", boolean_type, bloc));
...@@ -4539,6 +4539,7 @@ Build_recover_thunks::can_recover_arg(Location location) ...@@ -4539,6 +4539,7 @@ Build_recover_thunks::can_recover_arg(Location location)
args->push_back(zexpr); args->push_back(zexpr);
Expression* call = Expression::make_call(fn, args, false, location); Expression* call = Expression::make_call(fn, args, false, location);
call = Expression::make_unsafe_cast(uintptr_type, call, location);
args = new Expression_list(); args = new Expression_list();
args->push_back(call); args->push_back(call);
......
...@@ -60,8 +60,6 @@ enum Runtime_function_type ...@@ -60,8 +60,6 @@ enum Runtime_function_type
RFT_IFACE, RFT_IFACE,
// Go type interface{}, C type struct __go_empty_interface. // Go type interface{}, C type struct __go_empty_interface.
RFT_EFACE, RFT_EFACE,
// Go type func(unsafe.Pointer), C type void (*) (void *).
RFT_FUNC_PTR,
// Pointer to Go type descriptor. // Pointer to Go type descriptor.
RFT_TYPE, RFT_TYPE,
// [2]string. // [2]string.
...@@ -176,15 +174,6 @@ runtime_function_type(Runtime_function_type bft) ...@@ -176,15 +174,6 @@ runtime_function_type(Runtime_function_type bft)
t = Type::make_empty_interface_type(bloc); t = Type::make_empty_interface_type(bloc);
break; break;
case RFT_FUNC_PTR:
{
Typed_identifier_list* param_types = new Typed_identifier_list();
Type* ptrtype = runtime_function_type(RFT_POINTER);
param_types->push_back(Typed_identifier("", ptrtype, bloc));
t = Type::make_function_type(NULL, param_types, NULL, bloc);
}
break;
case RFT_TYPE: case RFT_TYPE:
t = Type::make_type_descriptor_ptr_type(); t = Type::make_type_descriptor_ptr_type();
break; break;
...@@ -265,7 +254,6 @@ convert_to_runtime_function_type(Runtime_function_type bft, Expression* e, ...@@ -265,7 +254,6 @@ convert_to_runtime_function_type(Runtime_function_type bft, Expression* e,
case RFT_COMPLEX128: case RFT_COMPLEX128:
case RFT_STRING: case RFT_STRING:
case RFT_POINTER: case RFT_POINTER:
case RFT_FUNC_PTR:
{ {
Type* t = runtime_function_type(bft); Type* t = runtime_function_type(bft);
if (!Type::are_identical(t, e->type(), true, NULL)) if (!Type::are_identical(t, e->type(), true, NULL))
......
...@@ -168,10 +168,10 @@ DEF_GO_RUNTIME(GORECOVER, "runtime.gorecover", P0(), R1(EFACE)) ...@@ -168,10 +168,10 @@ DEF_GO_RUNTIME(GORECOVER, "runtime.gorecover", P0(), R1(EFACE))
DEF_GO_RUNTIME(DEFERREDRECOVER, "runtime.deferredrecover", P0(), R1(EFACE)) DEF_GO_RUNTIME(DEFERREDRECOVER, "runtime.deferredrecover", P0(), R1(EFACE))
// Decide whether this function can call recover. // Decide whether this function can call recover.
DEF_GO_RUNTIME(CANRECOVER, "runtime.canrecover", P1(POINTER), R1(BOOL)) DEF_GO_RUNTIME(CANRECOVER, "runtime.canrecover", P1(UINTPTR), R1(BOOL))
// Set the return address for defer in a defer thunk. // Set the return address for defer in a defer thunk.
DEF_GO_RUNTIME(SETDEFERRETADDR, "runtime.setdeferretaddr", P1(POINTER), DEF_GO_RUNTIME(SETDEFERRETADDR, "runtime.setdeferretaddr", P1(UINTPTR),
R1(BOOL)) R1(BOOL))
// Check for a deferred function in an exception handler. // Check for a deferred function in an exception handler.
...@@ -213,10 +213,10 @@ DEF_GO_RUNTIME(REGISTER_GC_ROOTS, "runtime.registerGCRoots", P1(POINTER), R0()) ...@@ -213,10 +213,10 @@ DEF_GO_RUNTIME(REGISTER_GC_ROOTS, "runtime.registerGCRoots", P1(POINTER), R0())
DEF_GO_RUNTIME(NEW, "runtime.newobject", P1(TYPE), R1(POINTER)) DEF_GO_RUNTIME(NEW, "runtime.newobject", P1(TYPE), R1(POINTER))
// Start a new goroutine. // Start a new goroutine.
DEF_GO_RUNTIME(GO, "__go_go", P2(FUNC_PTR, POINTER), R0()) DEF_GO_RUNTIME(GO, "__go_go", P2(UINTPTR, POINTER), R1(POINTER))
// Defer a function. // Defer a function.
DEF_GO_RUNTIME(DEFERPROC, "runtime.deferproc", P3(BOOLPTR, FUNC_PTR, POINTER), DEF_GO_RUNTIME(DEFERPROC, "runtime.deferproc", P3(BOOLPTR, UINTPTR, POINTER),
R0()) R0())
...@@ -303,7 +303,7 @@ DEF_GO_RUNTIME(IFACEEFACEEQ, "runtime.ifaceefaceeq", P2(IFACE, EFACE), ...@@ -303,7 +303,7 @@ DEF_GO_RUNTIME(IFACEEFACEEQ, "runtime.ifaceefaceeq", P2(IFACE, EFACE),
// Set *dst = src where dst is a pointer to a pointer and src is a pointer. // Set *dst = src where dst is a pointer to a pointer and src is a pointer.
DEF_GO_RUNTIME(GCWRITEBARRIER, "runtime.gcWriteBarrier", DEF_GO_RUNTIME(GCWRITEBARRIER, "runtime.gcWriteBarrier",
P2(POINTER, POINTER), R0()) P2(POINTER, UINTPTR), R0())
// Set *dst = *src for an arbitrary type. // Set *dst = *src for an arbitrary type.
DEF_GO_RUNTIME(TYPEDMEMMOVE, "runtime.typedmemmove", DEF_GO_RUNTIME(TYPEDMEMMOVE, "runtime.typedmemmove",
......
...@@ -664,11 +664,19 @@ Gogo::write_barrier_variable() ...@@ -664,11 +664,19 @@ Gogo::write_barrier_variable()
{ {
Location bloc = Linemap::predeclared_location(); Location bloc = Linemap::predeclared_location();
// We pretend that writeBarrier is a uint32, so that we do a Type* bool_type = Type::lookup_bool_type();
// 32-bit load. That is what the gc toolchain does. Array_type* pad_type = Type::make_array_type(this->lookup_global("byte")->type_value(),
Type* uint32_type = Type::lookup_integer_type("uint32"); Expression::make_integer_ul(3, NULL, bloc));
Variable* var = new Variable(uint32_type, NULL, true, false, false, Type* uint64_type = Type::lookup_integer_type("uint64");
bloc); Type* wb_type = Type::make_builtin_struct_type(5,
"enabled", bool_type,
"pad", pad_type,
"needed", bool_type,
"cgo", bool_type,
"alignme", uint64_type);
Variable* var = new Variable(wb_type, NULL,
true, false, false, bloc);
bool add_to_globals; bool add_to_globals;
Package* package = this->add_imported_package("runtime", "_", false, Package* package = this->add_imported_package("runtime", "_", false,
...@@ -850,8 +858,12 @@ Gogo::assign_with_write_barrier(Function* function, Block* enclosing, ...@@ -850,8 +858,12 @@ Gogo::assign_with_write_barrier(Function* function, Block* enclosing,
case Type::TYPE_FUNCTION: case Type::TYPE_FUNCTION:
case Type::TYPE_MAP: case Type::TYPE_MAP:
case Type::TYPE_CHANNEL: case Type::TYPE_CHANNEL:
// These types are all represented by a single pointer. {
call = Runtime::make_call(Runtime::GCWRITEBARRIER, loc, 2, lhs, rhs); // These types are all represented by a single pointer.
Type* uintptr_type = Type::lookup_integer_type("uintptr");
rhs = Expression::make_unsafe_cast(uintptr_type, rhs, loc);
call = Runtime::make_call(Runtime::GCWRITEBARRIER, loc, 2, lhs, rhs);
}
break; break;
case Type::TYPE_STRING: case Type::TYPE_STRING:
...@@ -882,7 +894,17 @@ Gogo::check_write_barrier(Block* enclosing, Statement* without, ...@@ -882,7 +894,17 @@ Gogo::check_write_barrier(Block* enclosing, Statement* without,
{ {
Location loc = without->location(); Location loc = without->location();
Named_object* wb = this->write_barrier_variable(); Named_object* wb = this->write_barrier_variable();
// We pretend that writeBarrier is a uint32, so that we do a
// 32-bit load. That is what the gc toolchain does.
Type* void_type = Type::make_void_type();
Type* unsafe_pointer_type = Type::make_pointer_type(void_type);
Type* uint32_type = Type::lookup_integer_type("uint32");
Type* puint32_type = Type::make_pointer_type(uint32_type);
Expression* ref = Expression::make_var_reference(wb, loc); Expression* ref = Expression::make_var_reference(wb, loc);
ref = Expression::make_unary(OPERATOR_AND, ref, loc);
ref = Expression::make_cast(unsafe_pointer_type, ref, loc);
ref = Expression::make_cast(puint32_type, ref, loc);
ref = Expression::make_unary(OPERATOR_MULT, ref, loc);
Expression* zero = Expression::make_integer_ul(0, ref->type(), loc); Expression* zero = Expression::make_integer_ul(0, ref->type(), loc);
Expression* cond = Expression::make_binary(OPERATOR_EQEQ, ref, zero, loc); Expression* cond = Expression::make_binary(OPERATOR_EQEQ, ref, zero, loc);
......
...@@ -238,7 +238,7 @@ func setGCPercent(in int32) (out int32) { ...@@ -238,7 +238,7 @@ func setGCPercent(in int32) (out int32) {
var gcphase uint32 var gcphase uint32
// The compiler knows about this variable. // The compiler knows about this variable.
// If you change it, you must change builtin/runtime.go, too. // If you change it, you must change gofrontend/wb.cc, too.
// If you change the first four bytes, you must also change the write // If you change the first four bytes, you must also change the write
// barrier insertion code. // barrier insertion code.
var writeBarrier struct { var writeBarrier struct {
......
...@@ -112,7 +112,7 @@ func poll_runtime_isPollServerDescriptor(fd uintptr) bool { ...@@ -112,7 +112,7 @@ func poll_runtime_isPollServerDescriptor(fd uintptr) bool {
} }
//go:linkname poll_runtime_pollOpen internal..z2fpoll.runtime_pollOpen //go:linkname poll_runtime_pollOpen internal..z2fpoll.runtime_pollOpen
func poll_runtime_pollOpen(fd uintptr) (*pollDesc, int) { func poll_runtime_pollOpen(fd uintptr) (uintptr, int) {
pd := pollcache.alloc() pd := pollcache.alloc()
lock(&pd.lock) lock(&pd.lock)
if pd.wg != 0 && pd.wg != pdReady { if pd.wg != 0 && pd.wg != pdReady {
...@@ -133,11 +133,12 @@ func poll_runtime_pollOpen(fd uintptr) (*pollDesc, int) { ...@@ -133,11 +133,12 @@ func poll_runtime_pollOpen(fd uintptr) (*pollDesc, int) {
var errno int32 var errno int32
errno = netpollopen(fd, pd) errno = netpollopen(fd, pd)
return pd, int(errno) return uintptr(unsafe.Pointer(pd)), int(errno)
} }
//go:linkname poll_runtime_pollClose internal..z2fpoll.runtime_pollClose //go:linkname poll_runtime_pollClose internal..z2fpoll.runtime_pollClose
func poll_runtime_pollClose(pd *pollDesc) { func poll_runtime_pollClose(ctx uintptr) {
pd := (*pollDesc)(unsafe.Pointer(ctx))
if !pd.closing { if !pd.closing {
throw("runtime: close polldesc w/o unblock") throw("runtime: close polldesc w/o unblock")
} }
...@@ -159,7 +160,8 @@ func (c *pollCache) free(pd *pollDesc) { ...@@ -159,7 +160,8 @@ func (c *pollCache) free(pd *pollDesc) {
} }
//go:linkname poll_runtime_pollReset internal..z2fpoll.runtime_pollReset //go:linkname poll_runtime_pollReset internal..z2fpoll.runtime_pollReset
func poll_runtime_pollReset(pd *pollDesc, mode int) int { func poll_runtime_pollReset(ctx uintptr, mode int) int {
pd := (*pollDesc)(unsafe.Pointer(ctx))
err := netpollcheckerr(pd, int32(mode)) err := netpollcheckerr(pd, int32(mode))
if err != 0 { if err != 0 {
return err return err
...@@ -173,7 +175,8 @@ func poll_runtime_pollReset(pd *pollDesc, mode int) int { ...@@ -173,7 +175,8 @@ func poll_runtime_pollReset(pd *pollDesc, mode int) int {
} }
//go:linkname poll_runtime_pollWait internal..z2fpoll.runtime_pollWait //go:linkname poll_runtime_pollWait internal..z2fpoll.runtime_pollWait
func poll_runtime_pollWait(pd *pollDesc, mode int) int { func poll_runtime_pollWait(ctx uintptr, mode int) int {
pd := (*pollDesc)(unsafe.Pointer(ctx))
err := netpollcheckerr(pd, int32(mode)) err := netpollcheckerr(pd, int32(mode))
if err != 0 { if err != 0 {
return err return err
...@@ -195,7 +198,8 @@ func poll_runtime_pollWait(pd *pollDesc, mode int) int { ...@@ -195,7 +198,8 @@ func poll_runtime_pollWait(pd *pollDesc, mode int) int {
} }
//go:linkname poll_runtime_pollWaitCanceled internal..z2fpoll.runtime_pollWaitCanceled //go:linkname poll_runtime_pollWaitCanceled internal..z2fpoll.runtime_pollWaitCanceled
func poll_runtime_pollWaitCanceled(pd *pollDesc, mode int) { func poll_runtime_pollWaitCanceled(ctx uintptr, mode int) {
pd := (*pollDesc)(unsafe.Pointer(ctx))
// This function is used only on windows after a failed attempt to cancel // This function is used only on windows after a failed attempt to cancel
// a pending async IO operation. Wait for ioready, ignore closing or timeouts. // a pending async IO operation. Wait for ioready, ignore closing or timeouts.
for !netpollblock(pd, int32(mode), true) { for !netpollblock(pd, int32(mode), true) {
...@@ -203,7 +207,8 @@ func poll_runtime_pollWaitCanceled(pd *pollDesc, mode int) { ...@@ -203,7 +207,8 @@ func poll_runtime_pollWaitCanceled(pd *pollDesc, mode int) {
} }
//go:linkname poll_runtime_pollSetDeadline internal..z2fpoll.runtime_pollSetDeadline //go:linkname poll_runtime_pollSetDeadline internal..z2fpoll.runtime_pollSetDeadline
func poll_runtime_pollSetDeadline(pd *pollDesc, d int64, mode int) { func poll_runtime_pollSetDeadline(ctx uintptr, d int64, mode int) {
pd := (*pollDesc)(unsafe.Pointer(ctx))
lock(&pd.lock) lock(&pd.lock)
if pd.closing { if pd.closing {
unlock(&pd.lock) unlock(&pd.lock)
...@@ -288,7 +293,8 @@ func poll_runtime_pollSetDeadline(pd *pollDesc, d int64, mode int) { ...@@ -288,7 +293,8 @@ func poll_runtime_pollSetDeadline(pd *pollDesc, d int64, mode int) {
} }
//go:linkname poll_runtime_pollUnblock internal..z2fpoll.runtime_pollUnblock //go:linkname poll_runtime_pollUnblock internal..z2fpoll.runtime_pollUnblock
func poll_runtime_pollUnblock(pd *pollDesc) { func poll_runtime_pollUnblock(ctx uintptr) {
pd := (*pollDesc)(unsafe.Pointer(ctx))
lock(&pd.lock) lock(&pd.lock)
if pd.closing { if pd.closing {
throw("runtime: unblock on closing polldesc") throw("runtime: unblock on closing polldesc")
......
...@@ -153,7 +153,7 @@ var runtimeInitTime int64 ...@@ -153,7 +153,7 @@ var runtimeInitTime int64
var initSigmask sigset var initSigmask sigset
// The main goroutine. // The main goroutine.
func main() { func main(unsafe.Pointer) {
g := getg() g := getg()
// Max stack size is 1 GB on 64-bit, 250 MB on 32-bit. // Max stack size is 1 GB on 64-bit, 250 MB on 32-bit.
......
...@@ -283,8 +283,7 @@ func eqstring(x, y string) bool { ...@@ -283,8 +283,7 @@ func eqstring(x, y string) bool {
// For gccgo this is in the C code. // For gccgo this is in the C code.
func osyield() func osyield()
// For gccgo this can be called directly. //extern __go_syscall6
//extern syscall
func syscall(trap uintptr, a1, a2, a3, a4, a5, a6 uintptr) uintptr func syscall(trap uintptr, a1, a2, a3, a4, a5, a6 uintptr) uintptr
// For gccgo, to communicate from the C code to the Go code. // For gccgo, to communicate from the C code to the Go code.
......
...@@ -19,11 +19,8 @@ var ( ...@@ -19,11 +19,8 @@ var (
Stderr = 2 Stderr = 2
) )
//extern syscall //extern __go_syscall6
func c_syscall32(trap int32, a1, a2, a3, a4, a5, a6 int32) int32 func syscall6(trap uintptr, a1, a2, a3, a4, a5, a6 uintptr) uintptr
//extern syscall
func c_syscall64(trap int64, a1, a2, a3, a4, a5, a6 int64) int64
const ( const (
darwin64Bit = runtime.GOOS == "darwin" && sizeofPtr == 8 darwin64Bit = runtime.GOOS == "darwin" && sizeofPtr == 8
...@@ -38,14 +35,7 @@ const ( ...@@ -38,14 +35,7 @@ const (
func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) { func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
Entersyscall() Entersyscall()
SetErrno(0) SetErrno(0)
var r uintptr r := syscall6(trap, a1, a2, a3, 0, 0, 0)
if unsafe.Sizeof(r) == 4 {
r1 := c_syscall32(int32(trap), int32(a1), int32(a2), int32(a3), 0, 0, 0)
r = uintptr(r1)
} else {
r1 := c_syscall64(int64(trap), int64(a1), int64(a2), int64(a3), 0, 0, 0)
r = uintptr(r1)
}
err = GetErrno() err = GetErrno()
Exitsyscall() Exitsyscall()
return r, 0, err return r, 0, err
...@@ -54,47 +44,22 @@ func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) { ...@@ -54,47 +44,22 @@ func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) { func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
Entersyscall() Entersyscall()
SetErrno(0) SetErrno(0)
var r uintptr r := syscall6(trap, a1, a2, a3, a4, a5, a6)
if unsafe.Sizeof(r) == 4 {
r1 := c_syscall32(int32(trap), int32(a1), int32(a2), int32(a3),
int32(a4), int32(a5), int32(a6))
r = uintptr(r1)
} else {
r1 := c_syscall64(int64(trap), int64(a1), int64(a2), int64(a3),
int64(a4), int64(a5), int64(a6))
r = uintptr(r1)
}
err = GetErrno() err = GetErrno()
Exitsyscall() Exitsyscall()
return r, 0, err return r, 0, err
} }
func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) { func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
var r uintptr
SetErrno(0) SetErrno(0)
if unsafe.Sizeof(r) == 4 { r := syscall6(trap, a1, a2, a3, 0, 0, 0)
r1 := c_syscall32(int32(trap), int32(a1), int32(a2), int32(a3), 0, 0, 0)
r = uintptr(r1)
} else {
r1 := c_syscall64(int64(trap), int64(a1), int64(a2), int64(a3), 0, 0, 0)
r = uintptr(r1)
}
err = GetErrno() err = GetErrno()
return r, 0, err return r, 0, err
} }
func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) { func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
var r uintptr
SetErrno(0) SetErrno(0)
if unsafe.Sizeof(r) == 4 { r := syscall6(trap, a1, a2, a3, a4, a5, a6)
r1 := c_syscall32(int32(trap), int32(a1), int32(a2), int32(a3),
int32(a4), int32(a5), int32(a6))
r = uintptr(r1)
} else {
r1 := c_syscall64(int64(trap), int64(a1), int64(a2), int64(a3),
int64(a4), int64(a5), int64(a6))
r = uintptr(r1)
}
err = GetErrno() err = GetErrno()
return r, 0, err return r, 0, err
} }
......
...@@ -65,10 +65,10 @@ CoreDump (uint32_t *w) ...@@ -65,10 +65,10 @@ CoreDump (uint32_t *w)
return WCOREDUMP (*w) != 0; return WCOREDUMP (*w) != 0;
} }
extern int ExitStatus (uint32_t *w) extern intgo ExitStatus (uint32_t *w)
__asm__ (GOSYM_PREFIX "syscall.WaitStatus.ExitStatus"); __asm__ (GOSYM_PREFIX "syscall.WaitStatus.ExitStatus");
int intgo
ExitStatus (uint32_t *w) ExitStatus (uint32_t *w)
{ {
if (!WIFEXITED (*w)) if (!WIFEXITED (*w))
...@@ -76,10 +76,10 @@ ExitStatus (uint32_t *w) ...@@ -76,10 +76,10 @@ ExitStatus (uint32_t *w)
return WEXITSTATUS (*w); return WEXITSTATUS (*w);
} }
extern int Signal (uint32_t *w) extern intgo Signal (uint32_t *w)
__asm__ (GOSYM_PREFIX "syscall.WaitStatus.Signal"); __asm__ (GOSYM_PREFIX "syscall.WaitStatus.Signal");
int intgo
Signal (uint32_t *w) Signal (uint32_t *w)
{ {
if (!WIFSIGNALED (*w)) if (!WIFSIGNALED (*w))
...@@ -87,10 +87,10 @@ Signal (uint32_t *w) ...@@ -87,10 +87,10 @@ Signal (uint32_t *w)
return WTERMSIG (*w); return WTERMSIG (*w);
} }
extern int StopSignal (uint32_t *w) extern intgo StopSignal (uint32_t *w)
__asm__ (GOSYM_PREFIX "syscall.WaitStatus.StopSignal"); __asm__ (GOSYM_PREFIX "syscall.WaitStatus.StopSignal");
int intgo
StopSignal (uint32_t *w) StopSignal (uint32_t *w)
{ {
if (!WIFSTOPPED (*w)) if (!WIFSTOPPED (*w))
...@@ -98,10 +98,10 @@ StopSignal (uint32_t *w) ...@@ -98,10 +98,10 @@ StopSignal (uint32_t *w)
return WSTOPSIG (*w); return WSTOPSIG (*w);
} }
extern int TrapCause (uint32_t *w) extern intgo TrapCause (uint32_t *w)
__asm__ (GOSYM_PREFIX "syscall.WaitStatus.TrapCause"); __asm__ (GOSYM_PREFIX "syscall.WaitStatus.TrapCause");
int intgo
TrapCause (uint32_t *w __attribute__ ((unused))) TrapCause (uint32_t *w __attribute__ ((unused)))
{ {
#ifndef __linux__ #ifndef __linux__
......
...@@ -192,12 +192,12 @@ struct caller_ret ...@@ -192,12 +192,12 @@ struct caller_ret
_Bool ok; _Bool ok;
}; };
struct caller_ret Caller (int n) __asm__ (GOSYM_PREFIX "runtime.Caller"); struct caller_ret Caller (intgo n) __asm__ (GOSYM_PREFIX "runtime.Caller");
/* Implement runtime.Caller. */ /* Implement runtime.Caller. */
struct caller_ret struct caller_ret
Caller (int skip) Caller (intgo skip)
{ {
struct caller_ret ret; struct caller_ret ret;
Location loc; Location loc;
......
...@@ -236,11 +236,11 @@ runtime_callers (int32 skip, Location *locbuf, int32 m, bool keep_thunks) ...@@ -236,11 +236,11 @@ runtime_callers (int32 skip, Location *locbuf, int32 m, bool keep_thunks)
return data.index; return data.index;
} }
int Callers (int, struct __go_open_array) intgo Callers (intgo, struct __go_open_array)
__asm__ (GOSYM_PREFIX "runtime.Callers"); __asm__ (GOSYM_PREFIX "runtime.Callers");
int intgo
Callers (int skip, struct __go_open_array pc) Callers (intgo skip, struct __go_open_array pc)
{ {
Location *locbuf; Location *locbuf;
int ret; int ret;
......
...@@ -231,7 +231,7 @@ gostart (void *arg) ...@@ -231,7 +231,7 @@ gostart (void *arg)
setpagesize (getpagesize ()); setpagesize (getpagesize ());
runtime_sched = runtime_getsched(); runtime_sched = runtime_getsched();
runtime_schedinit (); runtime_schedinit ();
__go_go (runtime_main, NULL); __go_go ((uintptr)(runtime_main), NULL);
runtime_mstart (runtime_m ()); runtime_mstart (runtime_m ());
abort (); abort ();
} }
......
...@@ -55,7 +55,7 @@ main (int argc, char **argv) ...@@ -55,7 +55,7 @@ main (int argc, char **argv)
setpagesize (getpagesize ()); setpagesize (getpagesize ());
runtime_sched = runtime_getsched(); runtime_sched = runtime_getsched();
runtime_schedinit (); runtime_schedinit ();
__go_go (runtime_main, NULL); __go_go ((uintptr)(runtime_main), NULL);
runtime_mstart (runtime_m ()); runtime_mstart (runtime_m ());
abort (); abort ();
} }
...@@ -229,7 +229,8 @@ reflect_call (const struct __go_func_type *func_type, FuncVal *func_val, ...@@ -229,7 +229,8 @@ reflect_call (const struct __go_func_type *func_type, FuncVal *func_val,
call_result = (unsigned char *) malloc (go_results_size (func_type)); call_result = (unsigned char *) malloc (go_results_size (func_type));
ffi_call_go (&cif, func_val->fn, call_result, params, func_val); ffi_call_go (&cif, (void (*)(void)) func_val->fn, call_result, params,
func_val);
/* Some day we may need to free result values if RESULTS is /* Some day we may need to free result values if RESULTS is
NULL. */ NULL. */
......
...@@ -89,3 +89,14 @@ __go_openat (int fd, char *path, int flags, mode_t mode) ...@@ -89,3 +89,14 @@ __go_openat (int fd, char *path, int flags, mode_t mode)
} }
#endif #endif
// __go_syscall6 is called by both the runtime and syscall packages.
// We use uintptr_t to make sure that the types match, since the Go
// and C "int" types are not the same.
uintptr_t
__go_syscall6(uintptr_t flag, uintptr_t a1, uintptr_t a2, uintptr_t a3,
uintptr_t a4, uintptr_t a5, uintptr_t a6)
{
return syscall (flag, a1, a2, a3, a4, a5, a6);
}
...@@ -34,7 +34,7 @@ runtime_panicstring(const char *s) ...@@ -34,7 +34,7 @@ runtime_panicstring(const char *s)
runtime_throw("panic holding locks"); runtime_throw("panic holding locks");
} }
} }
runtime_newErrorCString(s, &err); runtime_newErrorCString((uintptr) s, &err);
runtime_panic(err); runtime_panic(err);
} }
......
...@@ -94,7 +94,7 @@ struct String ...@@ -94,7 +94,7 @@ struct String
struct FuncVal struct FuncVal
{ {
void (*fn)(void); uintptr_t fn;
// variable-size, fn-specific data here // variable-size, fn-specific data here
}; };
...@@ -295,7 +295,7 @@ void runtime_entersyscall() ...@@ -295,7 +295,7 @@ void runtime_entersyscall()
__asm__ (GOSYM_PREFIX "runtime.entersyscall"); __asm__ (GOSYM_PREFIX "runtime.entersyscall");
void runtime_entersyscallblock() void runtime_entersyscallblock()
__asm__ (GOSYM_PREFIX "runtime.entersyscallblock"); __asm__ (GOSYM_PREFIX "runtime.entersyscallblock");
G* __go_go(void (*pfn)(void*), void*); G* __go_go(uintptr, void*);
int32 runtime_callers(int32, Location*, int32, bool keep_callers); int32 runtime_callers(int32, Location*, int32, bool keep_callers);
int64 runtime_nanotime(void) // monotonic time int64 runtime_nanotime(void) // monotonic time
__asm__(GOSYM_PREFIX "runtime.nanotime"); __asm__(GOSYM_PREFIX "runtime.nanotime");
...@@ -389,7 +389,7 @@ void runtime_panic(Eface) ...@@ -389,7 +389,7 @@ void runtime_panic(Eface)
/* /*
* runtime c-called (but written in Go) * runtime c-called (but written in Go)
*/ */
void runtime_newErrorCString(const char*, Eface*) void runtime_newErrorCString(uintptr, Eface*)
__asm__ (GOSYM_PREFIX "runtime.NewErrorCString"); __asm__ (GOSYM_PREFIX "runtime.NewErrorCString");
/* /*
......
...@@ -20,7 +20,7 @@ extern void * __splitstack_find_context (void *context[10], size_t *, void **, ...@@ -20,7 +20,7 @@ extern void * __splitstack_find_context (void *context[10], size_t *, void **,
// tail call to doscanstack1. // tail call to doscanstack1.
#pragma GCC optimize ("-fno-optimize-sibling-calls") #pragma GCC optimize ("-fno-optimize-sibling-calls")
extern void scanstackblock(void *addr, uintptr size, void *gcw) extern void scanstackblock(uintptr addr, uintptr size, void *gcw)
__asm__("runtime.scanstackblock"); __asm__("runtime.scanstackblock");
static bool doscanstack1(G*, void*) static bool doscanstack1(G*, void*)
...@@ -84,11 +84,11 @@ static bool doscanstack1(G *gp, void *gcw) { ...@@ -84,11 +84,11 @@ static bool doscanstack1(G *gp, void *gcw) {
} }
} }
if(sp != nil) { if(sp != nil) {
scanstackblock(sp, (uintptr)(spsize), gcw); scanstackblock((uintptr)(sp), (uintptr)(spsize), gcw);
while((sp = __splitstack_find(next_segment, next_sp, while((sp = __splitstack_find(next_segment, next_sp,
&spsize, &next_segment, &spsize, &next_segment,
&next_sp, &initial_sp)) != nil) &next_sp, &initial_sp)) != nil)
scanstackblock(sp, (uintptr)(spsize), gcw); scanstackblock((uintptr)(sp), (uintptr)(spsize), gcw);
} }
#else #else
byte* bottom; byte* bottom;
......
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