From 6479ab2a752ba9ef714199de69d096cee0e6db2d Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Tue, 5 Jun 2018 17:14:47 +0200 Subject: Makefile, sys/targets: move all native compilation logic to sys/targets We currently have native cross-compilation logic duplicated in Makefile and in sys/targets. Some pieces are missed in one place, some are in another. Only pkg/csource knows how to check for -static support. Move all CC/CFLAGS logic to sys/targets and pull results in Makefile. This should make Makefile work on distros that have broken x86_64-linux-gnu-gcc, now we will use just gcc. And this removes the need to define NOSTATIC, as it's always auto-detected. This also paves the way for making pkg/csource work on OSes other than Linux. --- sys/syz-extract/extract.go | 2 +- sys/targets/targets.go | 153 ++++++++++++++++++++++++++++++++++----------- 2 files changed, 119 insertions(+), 36 deletions(-) (limited to 'sys') diff --git a/sys/syz-extract/extract.go b/sys/syz-extract/extract.go index 5dffaac9c..612e045db 100644 --- a/sys/syz-extract/extract.go +++ b/sys/syz-extract/extract.go @@ -104,7 +104,7 @@ func main() { buildDir = *flagSourceDir } - target := targets.List[osStr][archStr] + target := targets.Get(osStr, archStr) if target == nil { failf("unknown arch: %v", archStr) } diff --git a/sys/targets/targets.go b/sys/targets/targets.go index af946e3eb..5c41d8e66 100644 --- a/sys/targets/targets.go +++ b/sys/targets/targets.go @@ -3,26 +3,35 @@ package targets +import ( + "os" + "os/exec" + "runtime" + "strings" + "sync" +) + type Target struct { - os - OS string - Arch string - PtrSize uint64 - PageSize uint64 - NumPages uint64 - DataOffset uint64 - CArch []string - CFlags []string - CrossCFlags []string - CCompilerPrefix string - KernelArch string - KernelHeaderArch string - KernelCrossCompile string + init sync.Once + osCommon + OS string + Arch string + PtrSize uint64 + PageSize uint64 + NumPages uint64 + DataOffset uint64 + CArch []string + CFlags []string + CrossCFlags []string + CCompilerPrefix string + CCompiler string + KernelArch string + KernelHeaderArch string // NeedSyscallDefine is used by csource package to decide when to emit __NR_* defines. NeedSyscallDefine func(nr uint64) bool } -type os struct { +type osCommon struct { // Does the OS use syscall numbers (e.g. Linux) or has interface based on functions (e.g. fuchsia). SyscallNumbers bool // E.g. "__NR_" or "SYS_". @@ -32,8 +41,22 @@ type os struct { ExecutorUsesShmem bool // If ExecutorUsesForkServer, executor uses extended protocol with handshake. ExecutorUsesForkServer bool + // Extension of executable files (notably, .exe for windows). + ExeExtension string +} + +func Get(OS, arch string) *Target { + target := List[OS][arch] + if target == nil { + return nil + } + target.init.Do(func() { + checkStaticBuild(target) + }) + return target } +// nolint: lll var List = map[string]map[string]*Target{ "test": map[string]*Target{ "32": { @@ -51,7 +74,7 @@ var List = map[string]map[string]*Target{ PageSize: 4 << 10, CArch: []string{"__x86_64__"}, CFlags: []string{"-m64"}, - CrossCFlags: []string{"-m64"}, + CrossCFlags: []string{"-m64", "-static"}, CCompilerPrefix: "x86_64-linux-gnu-", KernelArch: "x86_64", KernelHeaderArch: "x86", @@ -66,7 +89,7 @@ var List = map[string]map[string]*Target{ PageSize: 4 << 10, CArch: []string{"__i386__"}, CFlags: []string{"-m32"}, - CrossCFlags: []string{"-m32"}, + CrossCFlags: []string{"-m32", "-static"}, CCompilerPrefix: "x86_64-linux-gnu-", KernelArch: "i386", KernelHeaderArch: "x86", @@ -75,6 +98,7 @@ var List = map[string]map[string]*Target{ PtrSize: 8, PageSize: 4 << 10, CArch: []string{"__aarch64__"}, + CrossCFlags: []string{"-static"}, CCompilerPrefix: "aarch64-linux-gnu-", KernelArch: "arm64", KernelHeaderArch: "arm64", @@ -84,7 +108,7 @@ var List = map[string]map[string]*Target{ PageSize: 4 << 10, CArch: []string{"__arm__"}, CFlags: []string{"-D__LINUX_ARM_ARCH__=6", "-m32", "-D__ARM_EABI__"}, - CrossCFlags: []string{"-D__LINUX_ARM_ARCH__=6", "-march=armv6t2"}, + CrossCFlags: []string{"-D__LINUX_ARM_ARCH__=6", "-march=armv6t2", "-static"}, CCompilerPrefix: "arm-linux-gnueabihf-", KernelArch: "arm", KernelHeaderArch: "arm", @@ -94,7 +118,7 @@ var List = map[string]map[string]*Target{ PageSize: 4 << 10, CArch: []string{"__ppc64__", "__PPC64__", "__powerpc64__"}, CFlags: []string{"-D__powerpc64__"}, - CrossCFlags: []string{"-D__powerpc64__"}, + CrossCFlags: []string{"-D__powerpc64__", "-static"}, CCompilerPrefix: "powerpc64le-linux-gnu-", KernelArch: "powerpc", KernelHeaderArch: "powerpc", @@ -102,18 +126,20 @@ var List = map[string]map[string]*Target{ }, "freebsd": map[string]*Target{ "amd64": { - PtrSize: 8, - PageSize: 4 << 10, - CArch: []string{"__x86_64__"}, - CFlags: []string{"-m64"}, + PtrSize: 8, + PageSize: 4 << 10, + CArch: []string{"__x86_64__"}, + CFlags: []string{"-m64"}, + CrossCFlags: []string{"-m64", "-static"}, }, }, "netbsd": map[string]*Target{ "amd64": { - PtrSize: 8, - PageSize: 4 << 10, - CArch: []string{"__x86_64__"}, - CFlags: []string{"-m64"}, + PtrSize: 8, + PageSize: 4 << 10, + CArch: []string{"__x86_64__"}, + CFlags: []string{"-m64"}, + CrossCFlags: []string{"-m64", "-static"}, }, }, "fuchsia": map[string]*Target{ @@ -122,12 +148,26 @@ var List = map[string]map[string]*Target{ PageSize: 4 << 10, CArch: []string{"__x86_64__"}, KernelHeaderArch: "x64", + CCompiler: os.ExpandEnv("${SOURCEDIR}/buildtools/linux-x64/clang/bin/clang"), + CrossCFlags: []string{ + "--target=x86_64-fuchsia", + "-lfdio", + "-lzircon", + "--sysroot", os.ExpandEnv("${SOURCEDIR}/out/build-zircon/build-x64/sysroot"), + }, }, "arm64": { PtrSize: 8, PageSize: 4 << 10, CArch: []string{"__aarch64__"}, KernelHeaderArch: "arm64", + CCompiler: os.ExpandEnv("${SOURCEDIR}/buildtools/linux-x64/clang/bin/clang"), + CrossCFlags: []string{ + "--target=aarch64-fuchsia", + "-lfdio", + "-lzircon", + "--sysroot", os.ExpandEnv("${SOURCEDIR}/out/build-zircon/build-arm64/sysroot"), + }, }, }, "windows": map[string]*Target{ @@ -144,11 +184,20 @@ var List = map[string]map[string]*Target{ PageSize: 4 << 10, CArch: []string{"__x86_64__"}, NeedSyscallDefine: dontNeedSyscallDefine, + CCompiler: os.ExpandEnv("${SOURCEDIR}/install/x86_64-ucb-akaros-gcc/bin/x86_64-ucb-akaros-g++"), + // Most likely this is incorrect (why doesn't it know own sysroot?), but worked for me. + CrossCFlags: []string{ + "-static", + "-I", os.ExpandEnv("${SOURCEDIR}/tools/compilers/gcc-glibc/x86_64-ucb-akaros-gcc-stage3-builddir/x86_64-ucb-akaros/libstdc++-v3/include/x86_64-ucb-akaros"), + "-I", os.ExpandEnv("${SOURCEDIR}/tools/compilers/gcc-glibc/x86_64-ucb-akaros-gcc-stage3-builddir/x86_64-ucb-akaros/libstdc++-v3/include"), + "-I", os.ExpandEnv("${SOURCEDIR}/tools/compilers/gcc-glibc/gcc-4.9.2/libstdc++-v3/libsupc++"), + "-L", os.ExpandEnv("${SOURCEDIR}/tools/compilers/gcc-glibc/x86_64-ucb-akaros-gcc-stage3-builddir/x86_64-ucb-akaros/libstdc++-v3/src/.libs"), + }, }, }, } -var oses = map[string]os{ +var oses = map[string]osCommon{ "linux": { SyscallNumbers: true, SyscallPrefix: "__NR_", @@ -176,6 +225,7 @@ var oses = map[string]os{ SyscallNumbers: false, ExecutorUsesShmem: false, ExecutorUsesForkServer: false, + ExeExtension: ".exe", }, "akaros": { SyscallNumbers: true, @@ -188,18 +238,51 @@ var oses = map[string]os{ func init() { for OS, archs := range List { for arch, target := range archs { - target.os = oses[OS] - target.OS = OS - target.Arch = arch - if target.NeedSyscallDefine == nil { - target.NeedSyscallDefine = needSyscallDefine + initTarget(target, OS, arch) + } + } +} + +func initTarget(target *Target, OS, arch string) { + target.osCommon = oses[OS] + target.OS = OS + target.Arch = arch + if target.NeedSyscallDefine == nil { + target.NeedSyscallDefine = needSyscallDefine + } + target.DataOffset = 512 << 20 + target.NumPages = (16 << 20) / target.PageSize + if OS == runtime.GOOS && arch == runtime.GOARCH { + // Don't use cross-compiler for native compilation, there are cases when this does not work: + // https://github.com/google/syzkaller/pull/619 + // https://github.com/google/syzkaller/issues/387 + // https://github.com/google/syzkaller/commit/06db3cec94c54e1cf720cdd5db72761514569d56 + target.CCompilerPrefix = "" + } + if target.CCompiler == "" { + target.CCompiler = target.CCompilerPrefix + "gcc" + } +} + +func checkStaticBuild(target *Target) { + for i, flag := range target.CrossCFlags { + if flag == "-static" { + // Some distributions don't have static libraries. + if !supportsStatic(target) { + copy(target.CrossCFlags[i:], target.CrossCFlags[i+1:]) + target.CrossCFlags = target.CrossCFlags[:len(target.CrossCFlags)-1] } - target.DataOffset = 512 << 20 - target.NumPages = (16 << 20) / target.PageSize + break } } } +func supportsStatic(target *Target) bool { + cmd := exec.Command(target.CCompiler, "-x", "c", "-", "-o", "/dev/null") + cmd.Stdin = strings.NewReader("int main(){}") + return cmd.Run() == nil +} + func needSyscallDefine(nr uint64) bool { return true } -- cgit mrf-deployment