mirror of
https://github.com/golang/go
synced 2024-11-14 09:00:21 -07:00
07cba70d57
Currently, for data moving, we generate an msanread of the source, followed by an msanwrite of the destination. msanread checks the source is initialized. This has a problem: if the source is an aggregate type containing alignment paddings, the padding bytes may not be thought as initialized by MSAN. If we copy the aggregate type by value, if it counts as a read, MSAN reports using uninitialized data. This CL changes it to use __msan_memmove for data copying, which tells MSAN to propagate initialized-ness but not check for it. Caveat: technically __msan_memmove is not a public API of MSAN, although the C compiler does generate direct calls to it. Also, when instrumenting a load of a struct, split the instrumentation to fields, instead of generating an msanread for the whole struct. This skips padding bytes, which may not be considered initialized in MSAN. Fixes #42820. Change-Id: Id861c8bbfd94cfcccefcc58eaf9e4eb43b4d85c6 Reviewed-on: https://go-review.googlesource.com/c/go/+/270859 Trust: Cherry Zhang <cherryyz@google.com> Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Austin Clements <austin@google.com>
39 lines
834 B
Go
39 lines
834 B
Go
// Copyright 2020 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.
|
|
|
|
package main
|
|
|
|
// Test passing C struct to exported Go function.
|
|
|
|
/*
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
|
|
// T is a C struct with alignment padding after b.
|
|
// The padding bytes are not considered initialized by MSAN.
|
|
// It is big enough to be passed on stack in C ABI (and least
|
|
// on AMD64).
|
|
typedef struct { char b; uintptr_t x, y; } T;
|
|
|
|
extern void F(T);
|
|
|
|
// Use weak as a hack to permit defining a function even though we use export.
|
|
void CF(int x) __attribute__ ((weak));
|
|
void CF(int x) {
|
|
T *t = malloc(sizeof(T));
|
|
t->b = (char)x;
|
|
t->x = x;
|
|
t->y = x;
|
|
F(*t);
|
|
}
|
|
*/
|
|
import "C"
|
|
|
|
//export F
|
|
func F(t C.T) { println(t.b, t.x, t.y) }
|
|
|
|
func main() {
|
|
C.CF(C.int(0))
|
|
}
|