gcc/libgo/go/internal/cpu/cpu_gccgo.c
Ian Lance Taylor 34489eb2af compiler: improve name mangling for packpaths
The current implementation of Gogo::pkgpath_for_symbol was written in
    a way that allowed two distinct package paths to map to the same
    symbol, which could cause collisions at link- time or compile-time.
    
    Switch to a better mangling scheme to insure that we get a unique
    packagepath symbol for each package. In the new scheme instead of having
    separate mangling schemes for identifiers and package paths, the
    main identifier mangler ("go_encode_id") now handles mangling of
    both packagepath characters and identifier characters.
    
    The new mangling scheme is more intrusive: "foo/bar.Baz" is mangled as
    "foo..z2fbar.Baz" instead of "foo_bar.Baz". To mitigate this, this
    patch also adds a demangling capability so that function names
    returned from runtime.CallersFrames are converted back to their
    original unmangled form.
    
    Changing the pkgpath_for_symbol scheme requires updating a number of
    //go:linkname directives and C "__asm__" directives to match the new
    scheme, as well as updating the 'gotest' driver (which makes
    assumptions about the correct mapping from pkgpath symbol to package
    name).
    
    Fixes golang/go#27534.
    
    Reviewed-on: https://go-review.googlesource.com/c/135455

From-SVN: r265510
2018-10-25 22:18:08 +00:00

73 lines
1.6 KiB
C

// Copyright 2018 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.
#include <stdint.h>
#if defined(__i386__) || defined(__x86_64__)
#include <cpuid.h>
#include <x86intrin.h>
#endif
#include "runtime.h"
#if defined(__i386__) || defined(__x86_64__)
struct cpuid_ret {
uint32_t eax;
uint32_t ebx;
uint32_t ecx;
uint32_t edx;
};
struct cpuid_ret cpuid(uint32_t, uint32_t)
__asm__(GOSYM_PREFIX "internal..z2fcpu.cpuid")
__attribute__((no_split_stack));
struct cpuid_ret cpuid(uint32_t eaxArg, uint32_t ecxArg) {
unsigned int eax = 0;
unsigned int ebx = 0;
unsigned int ecx = 0;
unsigned int edx = 0;
struct cpuid_ret ret;
__get_cpuid_count(eaxArg, ecxArg, &eax, &ebx, &ecx, &edx);
ret.eax = (uint32_t)(eax);
ret.ebx = (uint32_t)(ebx);
ret.ecx = (uint32_t)(ecx);
ret.edx = (uint32_t)(edx);
return ret;
}
struct xgetbv_ret {
uint32_t eax;
uint32_t edx;
};
struct xgetbv_ret xgetbv(void)
__asm__(GOSYM_PREFIX "internal..z2fcpu.xgetbv")
__attribute__((no_split_stack));
#pragma GCC push_options
#pragma GCC target("xsave")
struct xgetbv_ret xgetbv(void) {
struct xgetbv_ret ret;
// At some point, use call to _xgetbv() instead:
//
// long long r = _xgetbv(0);
// ret.eax = r & 0xffffffff;
// ret.edx = r >> 32;
//
unsigned int __eax, __edx, __xcr_no = 0;
__asm__ ("xgetbv" : "=a" (__eax), "=d" (__edx) : "c" (__xcr_no));
ret.eax = __eax;
ret.edx = __edx;
return ret;
}
#pragma GCC pop_options
#endif /* defined(__i386__) || defined(__x86_64__) */