On Thu, Jan 25, 2018 at 12:50 PM, Rainer Orth
<[email protected]> wrote:
>
>> From the error messages I guess the problem is that the assembler
>> doesn't like symbols that start with ".1". Do you know what names the
>> assembler permits?
>
> The x86 Assembly Language Reference Manual states:
Thanks. Looking back, it was actually not my plan to have symbols
that start with '.'. It was a bug, fixed by this patch. Bootstrapped
and ran Go testsuite on x86_64-pc-linux-gnu. Committed to mainline.
Ian
Index: gcc/go/gofrontend/MERGE
===================================================================
--- gcc/go/gofrontend/MERGE (revision 257061)
+++ gcc/go/gofrontend/MERGE (working copy)
@@ -1,4 +1,4 @@
-553e04735d1be372c596c720bcaea27e050b13a6
+203cbe7d3820fa03c965a01f72461f71588fe952
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
Index: gcc/go/gofrontend/go-encode-id.cc
===================================================================
--- gcc/go/gofrontend/go-encode-id.cc (revision 257033)
+++ gcc/go/gofrontend/go-encode-id.cc (working copy)
@@ -104,6 +104,14 @@ go_encode_id(const std::string &id)
std::string ret;
const char* p = id.c_str();
const char* pend = p + id.length();
+
+ // A leading ".0" is a space introduced before a mangled type name
+ // that starts with a 'u' or 'U', to avoid confusion with the
+ // mangling used here. We don't need a leading ".0", and we don't
+ // want symbols that start with '.', so remove it.
+ if (p[0] == '.' && p[1] == '0')
+ p += 2;
+
while (p < pend)
{
unsigned int c;
@@ -115,16 +123,19 @@ go_encode_id(const std::string &id)
go_assert(!char_needs_encoding(c));
ret += c;
}
- else if (c < 0x10000)
- {
- char buf[16];
- snprintf(buf, sizeof buf, "..u%04x", c);
- ret += buf;
- }
else
{
char buf[16];
- snprintf(buf, sizeof buf, "..U%08x", c);
+ if (c < 0x10000)
+ snprintf(buf, sizeof buf, "..u%04x", c);
+ else
+ snprintf(buf, sizeof buf, "..U%08x", c);
+
+ // We don't want a symbol to start with '.', so add a prefix
+ // if needed.
+ if (ret.empty())
+ ret += '_';
+
ret += buf;
}
p += len;
Index: gcc/go/gofrontend/names.cc
===================================================================
--- gcc/go/gofrontend/names.cc (revision 257033)
+++ gcc/go/gofrontend/names.cc (working copy)
@@ -213,7 +213,7 @@ Gogo::function_asm_name(const std::strin
{
std::string ret;
if (rtype != NULL)
- ret = rtype->mangled_name(this);
+ ret = rtype->deref()->mangled_name(this);
else if (package == NULL)
ret = this->pkgpath_symbol();
else
@@ -892,14 +892,7 @@ Named_type::append_mangled_type_name(Gog
const Typed_identifier* rcvr =
this->in_function_->func_value()->type()->receiver();
if (rcvr != NULL)
- {
- std::string m = rcvr->type()->mangled_name(gogo);
- // Turn a leading ".1" back into "*" since we are going
- // to type-mangle this name again.
- if (m.compare(0, 2, ".1") == 0)
- m = "*" + m.substr(2);
- ret->append(m);
- }
+ ret->append(rcvr->type()->deref()->mangled_name(gogo));
else if (this->in_function_->package() == NULL)
ret->append(gogo->pkgpath_symbol());
else
@@ -956,7 +949,7 @@ Gogo::type_descriptor_name(Type* type, N
const Typed_identifier* rcvr =
in_function->func_value()->type()->receiver();
if (rcvr != NULL)
- ret.append(rcvr->type()->mangled_name(this));
+ ret.append(rcvr->type()->deref()->mangled_name(this));
else if (in_function->package() == NULL)
ret.append(this->pkgpath_symbol());
else
Index: libgo/testsuite/gotest
===================================================================
--- libgo/testsuite/gotest (revision 256593)
+++ libgo/testsuite/gotest (working copy)
@@ -518,7 +518,7 @@ localname() {
pattern='Test([^a-z].*)?'
# The -p option tells GNU nm not to sort.
# The -v option tells Solaris nm to sort by value.
- tests=$($NM -p -v _gotest_.o $xofile | egrep " $text .*\."$pattern'$' |
grep -v '\..*\..*\.' | fgrep -v '$' | fgrep -v ' __go_' | sed 's/.* //' |
$symtogo)
+ tests=$($NM -p -v _gotest_.o $xofile | egrep " $text .*\."$pattern'$' |
grep -v '\..*\.' | fgrep -v '$' | fgrep -v ' __go_' | sed 's/.* //' | $symtogo)
if [ "x$tests" = x ]; then
echo 'gotest: warning: no tests matching '$pattern in
_gotest_.o $xofile 1>&2
exit 2
Index: libgo/go/runtime/pprof/pprof_test.go
===================================================================
--- libgo/go/runtime/pprof/pprof_test.go (revision 257033)
+++ libgo/go/runtime/pprof/pprof_test.go (working copy)
@@ -730,7 +730,7 @@ func TestMutexProfile(t *testing.T) {
stks := stacks(p)
for _, want := range [][]string{
// {"sync.(*Mutex).Unlock", "pprof.blockMutex.func1"},
- {".1sync.Mutex.Unlock", "pprof.blockMutex..func1"},
+ {"sync.Mutex.Unlock", "pprof.blockMutex..func1"},
} {
if !containsStack(stks, want) {
t.Errorf("No matching stack entry for %+v",
want)