compiler, libgo: change mangling scheme
Overhaul the mangling scheme to avoid ambiguities if the package path contains a dot. Instead of using dot both to separate components and to mangle characters, use dot only to separate components and use underscore to mangle characters. For golang/go#41862 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/271726
This commit is contained in:
parent
90bf60c3c2
commit
a01dda3c23
57 changed files with 1338 additions and 955 deletions
|
@ -1,4 +1,4 @@
|
|||
c948c2d770122932a05b62f653efa2c51f72d3ae
|
||||
b483d0e0a289ba5fcdbd0388cbc75393367ca870
|
||||
|
||||
The first line of this file holds the git revision number of the last
|
||||
merge done from the gofrontend repository.
|
||||
|
|
|
@ -226,7 +226,11 @@ Ast_dump_context::dump_type(const Type* t)
|
|||
// FIXME: write a type pretty printer instead of
|
||||
// using mangled names.
|
||||
if (this->gogo_ != NULL)
|
||||
this->ostream() << "(" << t->mangled_name(this->gogo_) << ")";
|
||||
{
|
||||
Backend_name bname;
|
||||
t->backend_name(this->gogo_, &bname);
|
||||
this->ostream() << "(" << bname.name() << ")";
|
||||
}
|
||||
}
|
||||
|
||||
// Dump a textual representation of a block to the
|
||||
|
|
|
@ -461,7 +461,7 @@ should_export(Named_object* no)
|
|||
return false;
|
||||
|
||||
// We don't export various special functions.
|
||||
if (Gogo::is_special_name(no->name()))
|
||||
if (Gogo::special_name_pos(no->name()) != std::string::npos)
|
||||
return false;
|
||||
|
||||
// Methods are exported with the type, not here.
|
||||
|
@ -524,7 +524,11 @@ struct Sort_types
|
|||
if (t1->classification() != t2->classification())
|
||||
return t1->classification() < t2->classification();
|
||||
Gogo* gogo = go_get_gogo();
|
||||
return gogo->type_descriptor_name(t1, NULL).compare(gogo->type_descriptor_name(t2, NULL)) < 0;
|
||||
Backend_name b1;
|
||||
gogo->type_descriptor_backend_name(t1, NULL, &b1);
|
||||
Backend_name b2;
|
||||
gogo->type_descriptor_backend_name(t2, NULL, &b2);
|
||||
return b1.name() < b2.name();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1596,7 +1596,8 @@ Func_descriptor_expression::do_get_backend(Translate_context* context)
|
|||
return context->backend()->var_expression(this->dvar_, loc);
|
||||
|
||||
Gogo* gogo = context->gogo();
|
||||
std::string var_name(gogo->function_descriptor_name(no));
|
||||
Backend_name bname;
|
||||
gogo->function_descriptor_backend_name(no, &bname);
|
||||
bool is_descriptor = false;
|
||||
if (no->is_function_declaration()
|
||||
&& !no->func_declaration_value()->asm_name().empty()
|
||||
|
@ -1616,10 +1617,11 @@ Func_descriptor_expression::do_get_backend(Translate_context* context)
|
|||
Btype* btype = this->type()->get_backend(gogo);
|
||||
|
||||
Bvariable* bvar;
|
||||
std::string asm_name(go_selectively_encode_id(var_name));
|
||||
if (no->package() != NULL || is_descriptor)
|
||||
bvar = context->backend()->immutable_struct_reference(var_name, asm_name,
|
||||
btype, loc);
|
||||
bvar =
|
||||
context->backend()->immutable_struct_reference(bname.name(),
|
||||
bname.optional_asm_name(),
|
||||
btype, loc);
|
||||
else
|
||||
{
|
||||
Location bloc = Linemap::predeclared_location();
|
||||
|
@ -1644,7 +1646,8 @@ Func_descriptor_expression::do_get_backend(Translate_context* context)
|
|||
if (no->is_function() && no->func_value()->is_referenced_by_inline())
|
||||
is_hidden = false;
|
||||
|
||||
bvar = context->backend()->immutable_struct(var_name, asm_name,
|
||||
bvar = context->backend()->immutable_struct(bname.name(),
|
||||
bname.optional_asm_name(),
|
||||
is_hidden, false,
|
||||
btype, bloc);
|
||||
Expression_list* vals = new Expression_list();
|
||||
|
@ -1654,8 +1657,9 @@ Func_descriptor_expression::do_get_backend(Translate_context* context)
|
|||
Translate_context bcontext(gogo, NULL, NULL, NULL);
|
||||
bcontext.set_is_const();
|
||||
Bexpression* binit = init->get_backend(&bcontext);
|
||||
context->backend()->immutable_struct_set_init(bvar, var_name, is_hidden,
|
||||
false, btype, bloc, binit);
|
||||
context->backend()->immutable_struct_set_init(bvar, bname.name(),
|
||||
is_hidden, false, btype,
|
||||
bloc, binit);
|
||||
}
|
||||
|
||||
this->dvar_ = bvar;
|
||||
|
@ -5190,11 +5194,9 @@ Unary_expression::do_get_backend(Translate_context* context)
|
|||
copy_to_heap = (context->function() != NULL
|
||||
|| context->is_const());
|
||||
}
|
||||
std::string asm_name(go_selectively_encode_id(var_name));
|
||||
Bvariable* implicit =
|
||||
gogo->backend()->implicit_variable(var_name, asm_name,
|
||||
btype, true, copy_to_heap,
|
||||
false, 0);
|
||||
gogo->backend()->implicit_variable(var_name, "", btype, true,
|
||||
copy_to_heap, false, 0);
|
||||
gogo->backend()->implicit_variable_set_init(implicit, var_name, btype,
|
||||
true, copy_to_heap, false,
|
||||
bexpr);
|
||||
|
@ -5219,10 +5221,9 @@ Unary_expression::do_get_backend(Translate_context* context)
|
|||
&& this->expr_->is_static_initializer())
|
||||
{
|
||||
std::string var_name(gogo->initializer_name());
|
||||
std::string asm_name(go_selectively_encode_id(var_name));
|
||||
Bvariable* decl =
|
||||
gogo->backend()->immutable_struct(var_name, asm_name,
|
||||
true, false, btype, loc);
|
||||
gogo->backend()->immutable_struct(var_name, "", true, false,
|
||||
btype, loc);
|
||||
gogo->backend()->immutable_struct_set_init(decl, var_name, true,
|
||||
false, btype, loc, bexpr);
|
||||
bexpr = gogo->backend()->var_expression(decl, loc);
|
||||
|
@ -5230,9 +5231,8 @@ Unary_expression::do_get_backend(Translate_context* context)
|
|||
else if (this->expr_->is_constant())
|
||||
{
|
||||
std::string var_name(gogo->initializer_name());
|
||||
std::string asm_name(go_selectively_encode_id(var_name));
|
||||
Bvariable* decl =
|
||||
gogo->backend()->implicit_variable(var_name, asm_name, btype,
|
||||
gogo->backend()->implicit_variable(var_name, "", btype,
|
||||
true, true, false, 0);
|
||||
gogo->backend()->implicit_variable_set_init(decl, var_name, btype,
|
||||
true, true, false,
|
||||
|
@ -18251,9 +18251,8 @@ Interface_mtable_expression::do_get_backend(Translate_context* context)
|
|||
{
|
||||
// The interface conversion table is defined elsewhere.
|
||||
Btype* btype = this->type()->get_backend(gogo);
|
||||
std::string asm_name(go_selectively_encode_id(mangled_name));
|
||||
this->bvar_ =
|
||||
gogo->backend()->immutable_struct_reference(mangled_name, asm_name,
|
||||
gogo->backend()->immutable_struct_reference(mangled_name, "",
|
||||
btype, loc);
|
||||
return gogo->backend()->var_expression(this->bvar_, this->location());
|
||||
}
|
||||
|
@ -18323,8 +18322,7 @@ Interface_mtable_expression::do_get_backend(Translate_context* context)
|
|||
Bexpression* ctor =
|
||||
gogo->backend()->constructor_expression(btype, ctor_bexprs, loc);
|
||||
|
||||
std::string asm_name(go_selectively_encode_id(mangled_name));
|
||||
this->bvar_ = gogo->backend()->immutable_struct(mangled_name, asm_name, false,
|
||||
this->bvar_ = gogo->backend()->immutable_struct(mangled_name, "", false,
|
||||
!is_public, btype, loc);
|
||||
gogo->backend()->immutable_struct_set_init(this->bvar_, mangled_name, false,
|
||||
!is_public, btype, loc, ctor);
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
#include "go-encode-id.h"
|
||||
#include "lex.h"
|
||||
|
||||
// Return whether the character c is OK to use in the assembler. We
|
||||
// only permit ASCII alphanumeric characters, underscore, and dot.
|
||||
// Return whether the character c can appear in a name that we are
|
||||
// encoding. We only permit ASCII alphanumeric characters.
|
||||
|
||||
static bool
|
||||
char_needs_encoding(char c)
|
||||
|
@ -32,7 +32,6 @@ char_needs_encoding(char c)
|
|||
case 'y': case 'z':
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
case '_': case '.':
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
|
@ -53,6 +52,52 @@ go_id_needs_encoding(const std::string& str)
|
|||
return false;
|
||||
}
|
||||
|
||||
// Map from characters to the underscore encoding for them.
|
||||
|
||||
class Special_char_code
|
||||
{
|
||||
public:
|
||||
Special_char_code();
|
||||
|
||||
// Return the simple underscore encoding for C, or 0 if none.
|
||||
char
|
||||
code_for(unsigned int c) const
|
||||
{
|
||||
if (c <= 127)
|
||||
return this->codes_[c];
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
// Encodings for characters.
|
||||
char codes_[128];
|
||||
};
|
||||
|
||||
// Construct the underscore encoding map.
|
||||
|
||||
Special_char_code::Special_char_code()
|
||||
{
|
||||
memset(this->codes_, 0, sizeof this->codes_);
|
||||
this->codes_['_'] = '_';
|
||||
this->codes_['.'] = '0';
|
||||
this->codes_['/'] = '1';
|
||||
this->codes_['*'] = '2';
|
||||
this->codes_[','] = '3';
|
||||
this->codes_['{'] = '4';
|
||||
this->codes_['}'] = '5';
|
||||
this->codes_['['] = '6';
|
||||
this->codes_[']'] = '7';
|
||||
this->codes_['('] = '8';
|
||||
this->codes_[')'] = '9';
|
||||
this->codes_['"'] = 'a';
|
||||
this->codes_[' '] = 'b';
|
||||
this->codes_[';'] = 'c';
|
||||
}
|
||||
|
||||
// The singleton Special_char_code.
|
||||
|
||||
static const Special_char_code special_char_code;
|
||||
|
||||
// Pull the next UTF-8 character out of P and store it in *PC. Return
|
||||
// the number of bytes read.
|
||||
|
||||
|
@ -82,10 +127,9 @@ fetch_utf8_char(const char* p, unsigned int* pc)
|
|||
return len;
|
||||
}
|
||||
|
||||
// Encode an identifier using assembler-friendly characters. The encoding is
|
||||
// described in detail near the end of the long comment at the start of
|
||||
// names.cc. Short version: translate all non-ASCII-alphanumeric characters into
|
||||
// ..uXXXX or ..UXXXXXXXX, translate ASCII non-alphanumerics into ".zXX".
|
||||
// Encode an identifier using assembler-friendly characters. The
|
||||
// encoding is described in detail near the end of the long comment at
|
||||
// the start of names.cc.
|
||||
|
||||
std::string
|
||||
go_encode_id(const std::string &id)
|
||||
|
@ -96,50 +140,57 @@ go_encode_id(const std::string &id)
|
|||
return id;
|
||||
}
|
||||
|
||||
// The encoding is only unambiguous if the input string does not
|
||||
// contain ..z, ..u or ..U.
|
||||
go_assert(id.find("..z") == std::string::npos);
|
||||
go_assert(id.find("..u") == std::string::npos);
|
||||
go_assert(id.find("..U") == std::string::npos);
|
||||
|
||||
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;
|
||||
// We encode a leading digit, to ensure that no identifier starts
|
||||
// with a digit.
|
||||
if (pend > p && p[0] >= '0' && p[0] <= '9')
|
||||
{
|
||||
char buf[8];
|
||||
snprintf(buf, sizeof buf, "_x%02x", p[0]);
|
||||
ret.append(buf);
|
||||
++p;
|
||||
}
|
||||
|
||||
while (p < pend)
|
||||
{
|
||||
unsigned int c;
|
||||
size_t len = fetch_utf8_char(p, &c);
|
||||
if (len == 1 && !char_needs_encoding(c))
|
||||
if (len == 1)
|
||||
{
|
||||
ret += c;
|
||||
if (!char_needs_encoding(c))
|
||||
ret.push_back(c);
|
||||
else
|
||||
{
|
||||
char code = special_char_code.code_for(c);
|
||||
if (code != 0)
|
||||
{
|
||||
ret.push_back('_');
|
||||
ret.push_back(code);
|
||||
}
|
||||
else
|
||||
{
|
||||
char buf[8];
|
||||
snprintf(buf, sizeof buf, "_x%02x", c);
|
||||
ret.append(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char buf[16];
|
||||
if (len == 1)
|
||||
snprintf(buf, sizeof buf, "..z%02x", c);
|
||||
else if (c < 0x10000)
|
||||
snprintf(buf, sizeof buf, "..u%04x", 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;
|
||||
snprintf(buf, sizeof buf, "_U%08x", c);
|
||||
ret.append(buf);
|
||||
}
|
||||
|
||||
p += len;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -170,64 +221,116 @@ go_decode_id(const std::string &encoded)
|
|||
const char* pend = p + encoded.length();
|
||||
const Location loc = Linemap::predeclared_location();
|
||||
|
||||
// Special case for initial "_", in case it was introduced
|
||||
// as a way to prevent encoded symbol starting with ".".
|
||||
if (*p == '_' && (strncmp(p+1, "..u", 3) == 0 || strncmp(p+1, "..U", 3) == 0))
|
||||
p++;
|
||||
|
||||
while (p < pend)
|
||||
{
|
||||
if (strncmp(p, "..z", 3) == 0)
|
||||
{
|
||||
const char* digits = p+3;
|
||||
if (strlen(digits) < 2)
|
||||
return "";
|
||||
unsigned rune = hex_digits_to_unicode_codepoint(digits, 2);
|
||||
Lex::append_char(rune, true, &ret, loc);
|
||||
p += 5;
|
||||
}
|
||||
else if (strncmp(p, "..u", 3) == 0)
|
||||
{
|
||||
const char* digits = p+3;
|
||||
if (strlen(digits) < 4)
|
||||
return "";
|
||||
unsigned rune = hex_digits_to_unicode_codepoint(digits, 4);
|
||||
Lex::append_char(rune, true, &ret, loc);
|
||||
p += 7;
|
||||
}
|
||||
else if (strncmp(p, "..U", 3) == 0)
|
||||
{
|
||||
const char* digits = p+3;
|
||||
if (strlen(digits) < 8)
|
||||
return "";
|
||||
unsigned rune = hex_digits_to_unicode_codepoint(digits, 8);
|
||||
Lex::append_char(rune, true, &ret, loc);
|
||||
p += 11;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret += *p;
|
||||
p += 1;
|
||||
}
|
||||
if (*p != '_' || p + 1 == pend)
|
||||
{
|
||||
ret.push_back(*p);
|
||||
p++;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (p[1])
|
||||
{
|
||||
case '_':
|
||||
ret.push_back('_');
|
||||
p += 2;
|
||||
break;
|
||||
case '0':
|
||||
ret.push_back('.');
|
||||
p += 2;
|
||||
break;
|
||||
case '1':
|
||||
ret.push_back('/');
|
||||
p += 2;
|
||||
break;
|
||||
case '2':
|
||||
ret.push_back('*');
|
||||
p += 2;
|
||||
break;
|
||||
case '3':
|
||||
ret.push_back(',');
|
||||
p += 2;
|
||||
break;
|
||||
case '4':
|
||||
ret.push_back('{');
|
||||
p += 2;
|
||||
break;
|
||||
case '5':
|
||||
ret.push_back('}');
|
||||
p += 2;
|
||||
break;
|
||||
case '6':
|
||||
ret.push_back('[');
|
||||
p += 2;
|
||||
break;
|
||||
case '7':
|
||||
ret.push_back(']');
|
||||
p += 2;
|
||||
break;
|
||||
case '8':
|
||||
ret.push_back('(');
|
||||
p += 2;
|
||||
break;
|
||||
case '9':
|
||||
ret.push_back(')');
|
||||
p += 2;
|
||||
break;
|
||||
case 'a':
|
||||
ret.push_back('"');
|
||||
p += 2;
|
||||
break;
|
||||
case 'b':
|
||||
ret.push_back(' ');
|
||||
p += 2;
|
||||
break;
|
||||
case 'c':
|
||||
ret.push_back(';');
|
||||
p += 2;
|
||||
break;
|
||||
case 'x':
|
||||
{
|
||||
const char* digits = p + 2;
|
||||
if (strlen(digits) < 2)
|
||||
return "";
|
||||
unsigned int rune = hex_digits_to_unicode_codepoint(digits, 2);
|
||||
Lex::append_char(rune, true, &ret, loc);
|
||||
p += 4;
|
||||
}
|
||||
break;
|
||||
case 'u':
|
||||
{
|
||||
const char* digits = p + 2;
|
||||
if (strlen(digits) < 4)
|
||||
return "";
|
||||
unsigned int rune = hex_digits_to_unicode_codepoint(digits, 4);
|
||||
Lex::append_char(rune, true, &ret, loc);
|
||||
p += 6;
|
||||
}
|
||||
break;
|
||||
case 'U':
|
||||
{
|
||||
const char* digits = p + 2;
|
||||
if (strlen(digits) < 8)
|
||||
return "";
|
||||
unsigned int rune = hex_digits_to_unicode_codepoint(digits, 8);
|
||||
Lex::append_char(rune, true, &ret, loc);
|
||||
p += 10;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string
|
||||
go_selectively_encode_id(const std::string &id)
|
||||
{
|
||||
if (go_id_needs_encoding(id))
|
||||
return go_encode_id(id);
|
||||
return std::string();
|
||||
}
|
||||
|
||||
// Encode a struct field tag. This is only used when we need to
|
||||
// create a type descriptor for an anonymous struct type with field
|
||||
// tags. This mangling is applied before go_encode_id. We skip
|
||||
// alphanumerics and underscore, replace every other single byte
|
||||
// character with .xNN, and leave larger UTF-8 characters for
|
||||
// go_encode_id.
|
||||
// tags. Underscore encoding will be applied to the returned string.
|
||||
// The tag will appear between curly braces, so that is all we have to
|
||||
// avoid.
|
||||
|
||||
std::string
|
||||
go_mangle_struct_tag(const std::string& tag)
|
||||
|
@ -241,28 +344,14 @@ go_mangle_struct_tag(const std::string& tag)
|
|||
size_t len = fetch_utf8_char(p, &c);
|
||||
if (len > 1)
|
||||
ret.append(p, len);
|
||||
else if (!char_needs_encoding(c) && c != '.')
|
||||
ret += c;
|
||||
else if (c != '{' && c != '}' && c != '\\')
|
||||
ret.push_back(c);
|
||||
else
|
||||
{
|
||||
char buf[16];
|
||||
snprintf(buf, sizeof buf, ".x%02x", c);
|
||||
ret += buf;
|
||||
ret.push_back('\\');
|
||||
ret.push_back(c);
|
||||
}
|
||||
p += len;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Encode a package path.
|
||||
|
||||
std::string
|
||||
go_mangle_pkgpath(const std::string& pkgpath)
|
||||
{
|
||||
std::string s = pkgpath;
|
||||
for (size_t i = s.find('.');
|
||||
i != std::string::npos;
|
||||
i = s.find('.', i + 1))
|
||||
s.replace(i, 1, ".x2e"); // 0x2e is the ASCII encoding for '.'
|
||||
return s;
|
||||
}
|
||||
|
|
|
@ -25,21 +25,8 @@ go_encode_id(const std::string &id);
|
|||
extern std::string
|
||||
go_decode_id(const std::string &id);
|
||||
|
||||
// Returns the empty string if the specified name needs encoding,
|
||||
// otherwise invokes go_encode_id on the name and returns the result.
|
||||
extern std::string
|
||||
go_selectively_encode_id(const std::string &id);
|
||||
|
||||
// Encodes a struct tag that appears in a type literal encoding.
|
||||
extern std::string
|
||||
go_mangle_struct_tag(const std::string& tag);
|
||||
|
||||
// Encode a package path. A package path can contain any arbitrary
|
||||
// character, including '.'. go_encode_id expects that any '.' will
|
||||
// be inserted by name mangling in a controlled manner. So first
|
||||
// translate any '.' using the same .x encoding as used by
|
||||
// go_mangle_struct_tag.
|
||||
extern std::string
|
||||
go_mangle_pkgpath(const std::string& pkgpath);
|
||||
|
||||
#endif // !defined(GO_ENCODE_ID_H)
|
||||
|
|
|
@ -299,7 +299,7 @@ void
|
|||
Gogo::set_pkgpath(const std::string& arg)
|
||||
{
|
||||
go_assert(!this->pkgpath_set_);
|
||||
this->pkgpath_ = go_mangle_pkgpath(arg);
|
||||
this->pkgpath_ = arg;
|
||||
this->pkgpath_set_ = true;
|
||||
this->pkgpath_from_option_ = true;
|
||||
}
|
||||
|
@ -324,32 +324,6 @@ Gogo::set_prefix(const std::string& arg)
|
|||
this->prefix_from_option_ = true;
|
||||
}
|
||||
|
||||
// Given a name which may or may not have been hidden, append the
|
||||
// appropriate version of the name to the result string. Take care
|
||||
// to avoid creating a sequence that will be rejected by go_encode_id
|
||||
// (avoid ..u, ..U, ..z).
|
||||
void
|
||||
Gogo::append_possibly_hidden_name(std::string *result, const std::string& name)
|
||||
{
|
||||
// FIXME: This adds in pkgpath twice for hidden symbols, which is
|
||||
// less than ideal.
|
||||
if (!Gogo::is_hidden_name(name))
|
||||
(*result) += name;
|
||||
else
|
||||
{
|
||||
std::string n = ".";
|
||||
std::string pkgpath = Gogo::hidden_name_pkgpath(name);
|
||||
char lastR = result->at(result->length() - 1);
|
||||
char firstP = pkgpath.at(0);
|
||||
if (lastR == '.' && (firstP == 'u' || firstP == 'U' || firstP == 'z'))
|
||||
n = "_.";
|
||||
n.append(pkgpath);
|
||||
n.append(1, '.');
|
||||
n.append(Gogo::unpack_hidden_name(name));
|
||||
(*result) += n;
|
||||
}
|
||||
}
|
||||
|
||||
// Munge name for use in an error message.
|
||||
|
||||
std::string
|
||||
|
@ -397,8 +371,7 @@ Gogo::set_package_name(const std::string& package_name,
|
|||
{
|
||||
if (!this->prefix_from_option_)
|
||||
this->prefix_ = "go";
|
||||
this->pkgpath_ = (go_mangle_pkgpath(this->prefix_) + '.'
|
||||
+ package_name);
|
||||
this->pkgpath_ = this->prefix_ + '.' + package_name;
|
||||
this->pkgpath_symbol_ = (Gogo::pkgpath_for_symbol(this->prefix_) + '.'
|
||||
+ Gogo::pkgpath_for_symbol(package_name));
|
||||
}
|
||||
|
@ -997,9 +970,9 @@ Gogo::register_type_descriptors(std::vector<Bstatement*>& init_stmts,
|
|||
it != this->imported_init_fns_.end();
|
||||
++it)
|
||||
{
|
||||
std::string pkgpath =
|
||||
this->pkgpath_from_init_fn_name((*it)->init_name());
|
||||
list_names.push_back(this->type_descriptor_list_symbol(pkgpath));
|
||||
std::string pkgpath_symbol =
|
||||
this->pkgpath_symbol_from_init_fn_name((*it)->init_name());
|
||||
list_names.push_back(this->type_descriptor_list_symbol(pkgpath_symbol));
|
||||
}
|
||||
// Add the main package itself.
|
||||
list_names.push_back(this->type_descriptor_list_symbol("main"));
|
||||
|
@ -2746,8 +2719,7 @@ Gogo::clear_file_scope()
|
|||
// parse tree is lowered.
|
||||
|
||||
void
|
||||
Gogo::queue_hash_function(Type* type, int64_t size,
|
||||
const std::string& hash_name,
|
||||
Gogo::queue_hash_function(Type* type, int64_t size, Backend_name* bname,
|
||||
Function_type* hash_fntype)
|
||||
{
|
||||
go_assert(!this->specific_type_functions_are_written_);
|
||||
|
@ -2755,7 +2727,7 @@ Gogo::queue_hash_function(Type* type, int64_t size,
|
|||
Specific_type_function::Specific_type_function_kind kind =
|
||||
Specific_type_function::SPECIFIC_HASH;
|
||||
Specific_type_function* tsf = new Specific_type_function(type, NULL, size,
|
||||
kind, hash_name,
|
||||
kind, bname,
|
||||
hash_fntype);
|
||||
this->specific_type_functions_.push_back(tsf);
|
||||
}
|
||||
|
@ -2766,15 +2738,14 @@ Gogo::queue_hash_function(Type* type, int64_t size,
|
|||
|
||||
void
|
||||
Gogo::queue_equal_function(Type* type, Named_type* name, int64_t size,
|
||||
const std::string& equal_name,
|
||||
Function_type* equal_fntype)
|
||||
Backend_name* bname, Function_type* equal_fntype)
|
||||
{
|
||||
go_assert(!this->specific_type_functions_are_written_);
|
||||
go_assert(!this->in_global_scope());
|
||||
Specific_type_function::Specific_type_function_kind kind =
|
||||
Specific_type_function::SPECIFIC_EQUAL;
|
||||
Specific_type_function* tsf = new Specific_type_function(type, name, size,
|
||||
kind, equal_name,
|
||||
kind, bname,
|
||||
equal_fntype);
|
||||
this->specific_type_functions_.push_back(tsf);
|
||||
}
|
||||
|
@ -2872,11 +2843,11 @@ Gogo::write_specific_type_functions()
|
|||
Specific_type_function* tsf = this->specific_type_functions_.back();
|
||||
this->specific_type_functions_.pop_back();
|
||||
if (tsf->kind == Specific_type_function::SPECIFIC_HASH)
|
||||
tsf->type->write_hash_function(this, tsf->size, tsf->fnname,
|
||||
tsf->type->write_hash_function(this, tsf->size, &tsf->bname,
|
||||
tsf->fntype);
|
||||
else
|
||||
tsf->type->write_equal_function(this, tsf->name, tsf->size,
|
||||
tsf->fnname, tsf->fntype);
|
||||
&tsf->bname, tsf->fntype);
|
||||
delete tsf;
|
||||
}
|
||||
this->specific_type_functions_are_written_ = true;
|
||||
|
@ -6218,6 +6189,56 @@ Function::import_func(Import* imp, std::string* pname,
|
|||
return true;
|
||||
}
|
||||
|
||||
// Get the backend name.
|
||||
|
||||
void
|
||||
Function::backend_name(Gogo* gogo, Named_object* no, Backend_name *bname)
|
||||
{
|
||||
if (!this->asm_name_.empty())
|
||||
bname->set_asm_name(this->asm_name_);
|
||||
else if (no->package() == NULL && no->name() == gogo->get_init_fn_name())
|
||||
{
|
||||
// These names appear in the export data and are used
|
||||
// directly in the assembler code. If we change this here
|
||||
// we need to change Gogo::init_imports.
|
||||
bname->set_asm_name(no->name());
|
||||
}
|
||||
else if (this->enclosing_ != NULL)
|
||||
{
|
||||
// Rewrite the nested name to use the enclosing function name.
|
||||
// We don't do this earlier because we just store simple names
|
||||
// in a Named_object, not Backend_names.
|
||||
|
||||
// The name was set by nested_function_name, which always
|
||||
// appends ..funcNNN. We want that to be our suffix.
|
||||
size_t pos = no->name().find("..func");
|
||||
go_assert(pos != std::string::npos);
|
||||
|
||||
Named_object* enclosing = this->enclosing_;
|
||||
while (true)
|
||||
{
|
||||
Named_object* parent = enclosing->func_value()->enclosing();
|
||||
if (parent == NULL)
|
||||
break;
|
||||
enclosing = parent;
|
||||
}
|
||||
|
||||
Type* rtype = NULL;
|
||||
if (enclosing->func_value()->type()->is_method())
|
||||
rtype = enclosing->func_value()->type()->receiver()->type();
|
||||
gogo->function_backend_name(enclosing->name(), enclosing->package(),
|
||||
rtype, bname);
|
||||
bname->append_suffix(no->name().substr(pos));
|
||||
}
|
||||
else
|
||||
{
|
||||
Type* rtype = NULL;
|
||||
if (this->type_->is_method())
|
||||
rtype = this->type_->receiver()->type();
|
||||
gogo->function_backend_name(no->name(), no->package(), rtype, bname);
|
||||
}
|
||||
}
|
||||
|
||||
// Get the backend representation.
|
||||
|
||||
Bfunction*
|
||||
|
@ -6226,7 +6247,6 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no)
|
|||
if (this->fndecl_ == NULL)
|
||||
{
|
||||
unsigned int flags = 0;
|
||||
bool is_init_fn = false;
|
||||
if (no->package() != NULL)
|
||||
{
|
||||
// Functions defined in other packages must be visible.
|
||||
|
@ -6238,10 +6258,7 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no)
|
|||
&& !this->type_->is_method())
|
||||
;
|
||||
else if (no->name() == gogo->get_init_fn_name())
|
||||
{
|
||||
flags |= Backend::function_is_visible;
|
||||
is_init_fn = true;
|
||||
}
|
||||
flags |= Backend::function_is_visible;
|
||||
else if (Gogo::unpack_hidden_name(no->name()) == "main"
|
||||
&& gogo->is_main_package())
|
||||
flags |= Backend::function_is_visible;
|
||||
|
@ -6255,29 +6272,13 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no)
|
|||
flags |= Backend::function_is_visible;
|
||||
}
|
||||
|
||||
Type* rtype = NULL;
|
||||
if (this->type_->is_method())
|
||||
rtype = this->type_->receiver()->type();
|
||||
|
||||
std::string asm_name;
|
||||
if (!this->asm_name_.empty())
|
||||
{
|
||||
asm_name = this->asm_name_;
|
||||
|
||||
// If an assembler name is explicitly specified, there must
|
||||
// be some reason to refer to the symbol from a different
|
||||
// object file.
|
||||
flags |= Backend::function_is_visible;
|
||||
}
|
||||
else if (is_init_fn)
|
||||
{
|
||||
// These names appear in the export data and are used
|
||||
// directly in the assembler code. If we change this here
|
||||
// we need to change Gogo::init_imports.
|
||||
asm_name = no->name();
|
||||
}
|
||||
else
|
||||
asm_name = gogo->function_asm_name(no->name(), no->package(), rtype);
|
||||
|
||||
// If an inline body refers to this function, then it
|
||||
// needs to be visible in the symbol table.
|
||||
|
@ -6337,13 +6338,36 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no)
|
|||
flags |= Backend::function_only_inline;
|
||||
|
||||
Btype* functype = this->type_->get_backend_fntype(gogo);
|
||||
this->fndecl_ =
|
||||
gogo->backend()->function(functype, no->get_id(gogo), asm_name,
|
||||
flags, this->location());
|
||||
|
||||
Backend_name bname;
|
||||
this->backend_name(gogo, no, &bname);
|
||||
|
||||
this->fndecl_ = gogo->backend()->function(functype,
|
||||
bname.name(),
|
||||
bname.optional_asm_name(),
|
||||
flags,
|
||||
this->location());
|
||||
}
|
||||
return this->fndecl_;
|
||||
}
|
||||
|
||||
// Get the backend name.
|
||||
|
||||
void
|
||||
Function_declaration::backend_name(Gogo* gogo, Named_object* no,
|
||||
Backend_name* bname)
|
||||
{
|
||||
if (!this->asm_name_.empty())
|
||||
bname->set_asm_name(this->asm_name_);
|
||||
else
|
||||
{
|
||||
Type* rtype = NULL;
|
||||
if (this->fntype_->is_method())
|
||||
rtype = this->fntype_->receiver()->type();
|
||||
gogo->function_backend_name(no->name(), no->package(), rtype, bname);
|
||||
}
|
||||
}
|
||||
|
||||
// Get the backend representation.
|
||||
|
||||
Bfunction*
|
||||
|
@ -6375,21 +6399,16 @@ Function_declaration::get_or_make_decl(Gogo* gogo, Named_object* no)
|
|||
flags |= Backend::function_does_not_return;
|
||||
}
|
||||
|
||||
std::string asm_name;
|
||||
if (this->asm_name_.empty())
|
||||
{
|
||||
Type* rtype = NULL;
|
||||
if (this->fntype_->is_method())
|
||||
rtype = this->fntype_->receiver()->type();
|
||||
asm_name = gogo->function_asm_name(no->name(), no->package(), rtype);
|
||||
}
|
||||
else if (go_id_needs_encoding(no->get_id(gogo)))
|
||||
asm_name = go_encode_id(no->get_id(gogo));
|
||||
|
||||
Btype* functype = this->fntype_->get_backend_fntype(gogo);
|
||||
this->fndecl_ =
|
||||
gogo->backend()->function(functype, no->get_id(gogo), asm_name,
|
||||
flags, this->location());
|
||||
|
||||
Backend_name bname;
|
||||
this->backend_name(gogo, no, &bname);
|
||||
|
||||
this->fndecl_ = gogo->backend()->function(functype,
|
||||
bname.name(),
|
||||
bname.optional_asm_name(),
|
||||
flags,
|
||||
this->location());
|
||||
}
|
||||
|
||||
return this->fndecl_;
|
||||
|
@ -7993,7 +8012,6 @@ Variable::get_backend_variable(Gogo* gogo, Named_object* function,
|
|||
type = Type::make_pointer_type(type);
|
||||
}
|
||||
|
||||
const std::string n = Gogo::unpack_hidden_name(name);
|
||||
Btype* btype = type->get_backend(gogo);
|
||||
|
||||
Bvariable* bvar;
|
||||
|
@ -8001,19 +8019,14 @@ Variable::get_backend_variable(Gogo* gogo, Named_object* function,
|
|||
bvar = Map_type::backend_zero_value(gogo);
|
||||
else if (this->is_global_)
|
||||
{
|
||||
std::string var_name(package != NULL
|
||||
? package->package_name()
|
||||
: gogo->package_name());
|
||||
var_name.push_back('.');
|
||||
var_name.append(n);
|
||||
|
||||
std::string asm_name(gogo->global_var_asm_name(name, package));
|
||||
Backend_name bname;
|
||||
gogo->global_var_backend_name(name, package, &bname);
|
||||
|
||||
bool is_hidden = Gogo::is_hidden_name(name);
|
||||
// Hack to export runtime.writeBarrier. FIXME.
|
||||
// This is because go:linkname doesn't work on variables.
|
||||
if (gogo->compiling_runtime()
|
||||
&& var_name == "runtime.writeBarrier")
|
||||
&& bname.name() == "runtime.writeBarrier")
|
||||
is_hidden = false;
|
||||
|
||||
// If an inline body refers to this variable, then it
|
||||
|
@ -8028,8 +8041,12 @@ Variable::get_backend_variable(Gogo* gogo, Named_object* function,
|
|||
if (package != NULL)
|
||||
is_hidden = false;
|
||||
|
||||
bvar = backend->global_variable(var_name,
|
||||
asm_name,
|
||||
// For some reason asm_name can't be the empty string
|
||||
// for global_variable, so we call asm_name rather than
|
||||
// optional_asm_name here. FIXME.
|
||||
|
||||
bvar = backend->global_variable(bname.name(),
|
||||
bname.asm_name(),
|
||||
btype,
|
||||
package != NULL,
|
||||
is_hidden,
|
||||
|
@ -8043,6 +8060,7 @@ Variable::get_backend_variable(Gogo* gogo, Named_object* function,
|
|||
}
|
||||
else
|
||||
{
|
||||
const std::string n = Gogo::unpack_hidden_name(name);
|
||||
Bfunction* bfunction = function->func_value()->get_decl();
|
||||
bool is_address_taken = (this->is_non_escaping_address_taken_
|
||||
&& !this->is_in_heap());
|
||||
|
@ -8216,7 +8234,13 @@ Named_constant::get_backend(Gogo* gogo, Named_object* const_no)
|
|||
if (type != NULL && type->is_numeric_type())
|
||||
{
|
||||
Btype* btype = type->get_backend(gogo);
|
||||
std::string name = const_no->get_id(gogo);
|
||||
std::string name;
|
||||
if (const_no->package() == NULL)
|
||||
name = gogo->pkgpath();
|
||||
else
|
||||
name = const_no->package()->pkgpath();
|
||||
name.push_back('.');
|
||||
name.append(Gogo::unpack_hidden_name(const_no->name()));
|
||||
const_decl =
|
||||
gogo->backend()->named_constant_expression(btype, name,
|
||||
const_decl, loc);
|
||||
|
@ -8637,54 +8661,6 @@ Named_object::get_backend_variable(Gogo* gogo, Named_object* function)
|
|||
go_unreachable();
|
||||
}
|
||||
|
||||
// Return the external identifier for this object.
|
||||
|
||||
std::string
|
||||
Named_object::get_id(Gogo* gogo)
|
||||
{
|
||||
go_assert(!this->is_variable()
|
||||
&& !this->is_result_variable()
|
||||
&& !this->is_type());
|
||||
std::string decl_name;
|
||||
if (this->is_function_declaration()
|
||||
&& !this->func_declaration_value()->asm_name().empty())
|
||||
decl_name = this->func_declaration_value()->asm_name();
|
||||
else
|
||||
{
|
||||
std::string package_name;
|
||||
if (this->package_ == NULL)
|
||||
package_name = gogo->package_name();
|
||||
else
|
||||
package_name = this->package_->package_name();
|
||||
|
||||
// Note that this will be misleading if this is an unexported
|
||||
// method generated for an embedded imported type. In that case
|
||||
// the unexported method should have the package name of the
|
||||
// package from which it is imported, but we are going to give
|
||||
// it our package name. Fixing this would require knowing the
|
||||
// package name, but we only know the package path. It might be
|
||||
// better to use package paths here anyhow. This doesn't affect
|
||||
// the assembler code, because we always set that name in
|
||||
// Function::get_or_make_decl anyhow. FIXME.
|
||||
|
||||
decl_name = package_name + '.' + Gogo::unpack_hidden_name(this->name_);
|
||||
|
||||
Function_type* fntype;
|
||||
if (this->is_function())
|
||||
fntype = this->func_value()->type();
|
||||
else if (this->is_function_declaration())
|
||||
fntype = this->func_declaration_value()->type();
|
||||
else
|
||||
fntype = NULL;
|
||||
if (fntype != NULL && fntype->is_method())
|
||||
{
|
||||
decl_name.push_back('.');
|
||||
decl_name.append(fntype->receiver()->type()->mangled_name(gogo));
|
||||
}
|
||||
}
|
||||
return decl_name;
|
||||
}
|
||||
|
||||
void
|
||||
debug_go_named_object(Named_object* no)
|
||||
{
|
||||
|
|
|
@ -57,6 +57,101 @@ class Node;
|
|||
// This file declares the basic classes used to hold the internal
|
||||
// representation of Go which is built by the parser.
|
||||
|
||||
// The name of some backend object. Backend objects have a
|
||||
// user-visible name and an assembler name. The user visible name
|
||||
// might include arbitrary Unicode characters. The assembler name
|
||||
// will not.
|
||||
|
||||
class Backend_name
|
||||
{
|
||||
public:
|
||||
Backend_name()
|
||||
: prefix_(NULL), components_(), count_(0), suffix_(),
|
||||
is_asm_name_(false)
|
||||
{}
|
||||
|
||||
// Set the prefix. Prefixes are always constant strings.
|
||||
void
|
||||
set_prefix(const char* p)
|
||||
{
|
||||
go_assert(this->prefix_ == NULL && !this->is_asm_name_);
|
||||
this->prefix_ = p;
|
||||
}
|
||||
|
||||
// Set the suffix.
|
||||
void
|
||||
set_suffix(const std::string& s)
|
||||
{
|
||||
go_assert(this->suffix_.empty() && !this->is_asm_name_);
|
||||
this->suffix_ = s;
|
||||
}
|
||||
|
||||
// Append to the suffix.
|
||||
void
|
||||
append_suffix(const std::string& s)
|
||||
{
|
||||
if (this->is_asm_name_)
|
||||
this->components_[0].append(s);
|
||||
else
|
||||
this->suffix_.append(s);
|
||||
}
|
||||
|
||||
// Add a component.
|
||||
void
|
||||
add(const std::string& c)
|
||||
{
|
||||
go_assert(this->count_ < Backend_name::max_components
|
||||
&& !this->is_asm_name_);
|
||||
this->components_[this->count_] = c;
|
||||
++this->count_;
|
||||
}
|
||||
|
||||
// Set an assembler name specified by the user. This overrides both
|
||||
// the user-visible name and the assembler name. No further
|
||||
// encoding is applied.
|
||||
void
|
||||
set_asm_name(const std::string& n)
|
||||
{
|
||||
go_assert(this->prefix_ == NULL
|
||||
&& this->count_ == 0
|
||||
&& this->suffix_.empty()
|
||||
&& !this->is_asm_name_);
|
||||
this->components_[0] = n;
|
||||
this->is_asm_name_ = true;
|
||||
}
|
||||
|
||||
// Get the user visible name.
|
||||
std::string
|
||||
name() const;
|
||||
|
||||
// Get the assembler name. This may be the same as the user visible
|
||||
// name.
|
||||
std::string
|
||||
asm_name() const;
|
||||
|
||||
// Get an optional assembler name: if it would be the same as the
|
||||
// user visible name, this returns the empty string.
|
||||
std::string
|
||||
optional_asm_name() const;
|
||||
|
||||
private:
|
||||
// The maximum number of components.
|
||||
static const int max_components = 4;
|
||||
|
||||
// An optional prefix that does not require encoding.
|
||||
const char *prefix_;
|
||||
// Up to four components. The name will include these components
|
||||
// separated by dots. Each component will be underscore-encoded
|
||||
// (see the long comment near the top of names.cc).
|
||||
std::string components_[Backend_name::max_components];
|
||||
// Number of components.
|
||||
int count_;
|
||||
// An optional suffix that does not require encoding.
|
||||
std::string suffix_;
|
||||
// True if components_[0] is an assembler name specified by the user.
|
||||
bool is_asm_name_;
|
||||
};
|
||||
|
||||
// An initialization function for an imported package. This is a
|
||||
// magic function which initializes variables and runs the "init"
|
||||
// function.
|
||||
|
@ -613,7 +708,7 @@ class Gogo
|
|||
// is used when a type-specific hash function is needed when not at
|
||||
// top level.
|
||||
void
|
||||
queue_hash_function(Type* type, int64_t size, const std::string& hash_name,
|
||||
queue_hash_function(Type* type, int64_t size, Backend_name*,
|
||||
Function_type* hash_fntype);
|
||||
|
||||
// Queue up a type-specific equal function to be written out. This
|
||||
|
@ -621,8 +716,7 @@ class Gogo
|
|||
// top level.
|
||||
void
|
||||
queue_equal_function(Type* type, Named_type* name, int64_t size,
|
||||
const std::string& equal_name,
|
||||
Function_type* equal_fntype);
|
||||
Backend_name*, Function_type* equal_fntype);
|
||||
|
||||
// Write out queued specific type functions.
|
||||
void
|
||||
|
@ -869,31 +963,32 @@ class Gogo
|
|||
Expression*
|
||||
allocate_memory(Type *type, Location);
|
||||
|
||||
// Return the assembler name to use for an exported function, a
|
||||
// method, or a function/method declaration.
|
||||
std::string
|
||||
function_asm_name(const std::string& go_name, const Package*,
|
||||
const Type* receiver);
|
||||
// Get the backend name to use for an exported function, a method,
|
||||
// or a function/method declaration.
|
||||
void
|
||||
function_backend_name(const std::string& go_name, const Package*,
|
||||
const Type* receiver, Backend_name*);
|
||||
|
||||
// Return the name to use for a function descriptor.
|
||||
std::string
|
||||
function_descriptor_name(Named_object*);
|
||||
void
|
||||
function_descriptor_backend_name(Named_object*, Backend_name*);
|
||||
|
||||
// Return the name to use for a generated stub method.
|
||||
std::string
|
||||
stub_method_name(const Package*, const std::string& method_name);
|
||||
|
||||
// Return the name of the hash function for TYPE.
|
||||
std::string
|
||||
hash_function_name(const Type*);
|
||||
// Get the backend name of the hash function for TYPE.
|
||||
void
|
||||
hash_function_name(const Type*, Backend_name*);
|
||||
|
||||
// Return the name of the equal function for TYPE.
|
||||
std::string
|
||||
equal_function_name(const Type*, const Named_type*);
|
||||
// Get the backend name of the equal function for TYPE.
|
||||
void
|
||||
equal_function_name(const Type*, const Named_type*, Backend_name*);
|
||||
|
||||
// Return the assembler name to use for a global variable.
|
||||
std::string
|
||||
global_var_asm_name(const std::string& go_name, const Package*);
|
||||
// Get the backend name to use for a global variable.
|
||||
void
|
||||
global_var_backend_name(const std::string& go_name, const Package*,
|
||||
Backend_name*);
|
||||
|
||||
// Return a name to use for an error case. This should only be used
|
||||
// after reporting an error, and is used to avoid useless knockon
|
||||
|
@ -961,13 +1056,14 @@ class Gogo
|
|||
// Return the package path symbol from an init function name, which
|
||||
// can be a real init function or a dummy one.
|
||||
std::string
|
||||
pkgpath_from_init_fn_name(std::string);
|
||||
pkgpath_symbol_from_init_fn_name(std::string);
|
||||
|
||||
// Return the name for a type descriptor symbol.
|
||||
std::string
|
||||
type_descriptor_name(const Type*, Named_type*);
|
||||
// Get the backend name for a type descriptor symbol.
|
||||
void
|
||||
type_descriptor_backend_name(const Type*, Named_type*, Backend_name*);
|
||||
|
||||
// Return the name of the type descriptor list symbol of a package.
|
||||
// The argument is an encoded pkgpath, as with pkgpath_symbol.
|
||||
std::string
|
||||
type_descriptor_list_symbol(const std::string&);
|
||||
|
||||
|
@ -987,11 +1083,11 @@ class Gogo
|
|||
std::string
|
||||
interface_method_table_name(Interface_type*, Type*, bool is_pointer);
|
||||
|
||||
// Return whether NAME is a special name that can not be passed to
|
||||
// unpack_hidden_name. This is needed because various special names
|
||||
// use "..SUFFIX", but unpack_hidden_name just looks for '.'.
|
||||
static bool
|
||||
is_special_name(const std::string& name);
|
||||
// If NAME is a special name used as a Go identifier, return the
|
||||
// position within the string where the special part of the name
|
||||
// occurs.
|
||||
static size_t
|
||||
special_name_pos(const std::string& name);
|
||||
|
||||
private:
|
||||
// During parsing, we keep a stack of functions. Each function on
|
||||
|
@ -1056,6 +1152,9 @@ class Gogo
|
|||
Named_object*
|
||||
write_barrier_variable();
|
||||
|
||||
static bool
|
||||
is_digits(const std::string&);
|
||||
|
||||
// Type used to map import names to packages.
|
||||
typedef std::map<std::string, Package*> Imports;
|
||||
|
||||
|
@ -1079,15 +1178,15 @@ class Gogo
|
|||
Named_type* name;
|
||||
int64_t size;
|
||||
Specific_type_function_kind kind;
|
||||
std::string fnname;
|
||||
Backend_name bname;
|
||||
Function_type* fntype;
|
||||
|
||||
Specific_type_function(Type* atype, Named_type* aname, int64_t asize,
|
||||
Specific_type_function_kind akind,
|
||||
const std::string& afnname,
|
||||
Backend_name* abname,
|
||||
Function_type* afntype)
|
||||
: type(atype), name(aname), size(asize), kind(akind),
|
||||
fnname(afnname), fntype(afntype)
|
||||
bname(*abname), fntype(afntype)
|
||||
{ }
|
||||
};
|
||||
|
||||
|
@ -1631,6 +1730,10 @@ class Function
|
|||
Bstatement*
|
||||
return_value(Gogo*, Named_object*, Location) const;
|
||||
|
||||
// Get the backend name of this function.
|
||||
void
|
||||
backend_name(Gogo*, Named_object*, Backend_name*);
|
||||
|
||||
// Get an expression for the variable holding the defer stack.
|
||||
Expression*
|
||||
defer_stack(Location);
|
||||
|
@ -1872,6 +1975,10 @@ class Function_declaration
|
|||
void
|
||||
build_backend_descriptor(Gogo*);
|
||||
|
||||
// Get the backend name of this function declaration.
|
||||
void
|
||||
backend_name(Gogo*, Named_object*, Backend_name*);
|
||||
|
||||
// Export a function declaration.
|
||||
void
|
||||
export_func(Export* exp, const Named_object* no) const
|
||||
|
@ -2863,10 +2970,6 @@ class Named_object
|
|||
Bvariable*
|
||||
get_backend_variable(Gogo*, Named_object* function);
|
||||
|
||||
// Return the external identifier for this object.
|
||||
std::string
|
||||
get_id(Gogo*);
|
||||
|
||||
// Get the backend representation of this object.
|
||||
void
|
||||
get_backend(Gogo*, std::vector<Bexpression*>&, std::vector<Btype*>&,
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -83,7 +83,7 @@ DEF_GO_RUNTIME(MAKEMAP64, "runtime.makemap64", P3(TYPE, INT64, POINTER),
|
|||
R1(MAP))
|
||||
|
||||
// Make a map with no hint, or a small constant hint.
|
||||
DEF_GO_RUNTIME(MAKEMAP_SMALL, "runtime.makemap_small", P0(), R1(MAP))
|
||||
DEF_GO_RUNTIME(MAKEMAP_SMALL, "runtime.makemap__small", P0(), R1(MAP))
|
||||
|
||||
// Build a map from a composite literal.
|
||||
DEF_GO_RUNTIME(CONSTRUCT_MAP, "__go_construct_map",
|
||||
|
@ -95,19 +95,19 @@ DEF_GO_RUNTIME(MAPACCESS1, "runtime.mapaccess1", P3(TYPE, MAP, POINTER),
|
|||
R1(POINTER))
|
||||
|
||||
// Look up a uint32 key in a map.
|
||||
DEF_GO_RUNTIME(MAPACCESS1_FAST32, "runtime.mapaccess1_fast32",
|
||||
DEF_GO_RUNTIME(MAPACCESS1_FAST32, "runtime.mapaccess1__fast32",
|
||||
P3(TYPE, MAP, UINT32), R1(POINTER))
|
||||
|
||||
// Look up a uint64 key in a map.
|
||||
DEF_GO_RUNTIME(MAPACCESS1_FAST64, "runtime.mapaccess1_fast64",
|
||||
DEF_GO_RUNTIME(MAPACCESS1_FAST64, "runtime.mapaccess1__fast64",
|
||||
P3(TYPE, MAP, UINT64), R1(POINTER))
|
||||
|
||||
// Look up a string key in a map.
|
||||
DEF_GO_RUNTIME(MAPACCESS1_FASTSTR, "runtime.mapaccess1_faststr",
|
||||
DEF_GO_RUNTIME(MAPACCESS1_FASTSTR, "runtime.mapaccess1__faststr",
|
||||
P3(TYPE, MAP, STRING), R1(POINTER))
|
||||
|
||||
// Look up a key in a map when the value is large.
|
||||
DEF_GO_RUNTIME(MAPACCESS1_FAT, "runtime.mapaccess1_fat",
|
||||
DEF_GO_RUNTIME(MAPACCESS1_FAT, "runtime.mapaccess1__fat",
|
||||
P4(TYPE, MAP, POINTER, POINTER), R1(POINTER))
|
||||
|
||||
// Look up a key in a map returning the value and whether it is
|
||||
|
@ -117,22 +117,22 @@ DEF_GO_RUNTIME(MAPACCESS2, "runtime.mapaccess2", P3(TYPE, MAP, POINTER),
|
|||
|
||||
// Look up a uint32 key in a map returning the value and whether
|
||||
// it is present.
|
||||
DEF_GO_RUNTIME(MAPACCESS2_FAST32, "runtime.mapaccess2_fast32",
|
||||
DEF_GO_RUNTIME(MAPACCESS2_FAST32, "runtime.mapaccess2__fast32",
|
||||
P3(TYPE, MAP, UINT32), R2(POINTER, BOOL))
|
||||
|
||||
// Look up a uint64 key in a map returning the value and whether
|
||||
// it is present.
|
||||
DEF_GO_RUNTIME(MAPACCESS2_FAST64, "runtime.mapaccess2_fast64",
|
||||
DEF_GO_RUNTIME(MAPACCESS2_FAST64, "runtime.mapaccess2__fast64",
|
||||
P3(TYPE, MAP, UINT64), R2(POINTER, BOOL))
|
||||
|
||||
// Look up a string key in a map returning the value and whether
|
||||
// it is present.
|
||||
DEF_GO_RUNTIME(MAPACCESS2_FASTSTR, "runtime.mapaccess2_faststr",
|
||||
DEF_GO_RUNTIME(MAPACCESS2_FASTSTR, "runtime.mapaccess2__faststr",
|
||||
P3(TYPE, MAP, STRING), R2(POINTER, BOOL))
|
||||
|
||||
// Look up a key in a map, returning the value and whether it is
|
||||
// present, when the value is large.
|
||||
DEF_GO_RUNTIME(MAPACCESS2_FAT, "runtime.mapaccess2_fat",
|
||||
DEF_GO_RUNTIME(MAPACCESS2_FAT, "runtime.mapaccess2__fat",
|
||||
P4(TYPE, MAP, POINTER, POINTER), R2(POINTER, BOOL))
|
||||
|
||||
// Assignment to a key in a map.
|
||||
|
@ -140,38 +140,38 @@ DEF_GO_RUNTIME(MAPASSIGN, "runtime.mapassign", P3(TYPE, MAP, POINTER),
|
|||
R1(POINTER))
|
||||
|
||||
// Assignment to a uint32 key in a map.
|
||||
DEF_GO_RUNTIME(MAPASSIGN_FAST32, "runtime.mapassign_fast32",
|
||||
DEF_GO_RUNTIME(MAPASSIGN_FAST32, "runtime.mapassign__fast32",
|
||||
P3(TYPE, MAP, UINT32), R1(POINTER))
|
||||
|
||||
// Assignment to a uint64 key in a map.
|
||||
DEF_GO_RUNTIME(MAPASSIGN_FAST64, "runtime.mapassign_fast64",
|
||||
DEF_GO_RUNTIME(MAPASSIGN_FAST64, "runtime.mapassign__fast64",
|
||||
P3(TYPE, MAP, UINT64), R1(POINTER))
|
||||
|
||||
// Assignment to a 32-bit pointer key in a map.
|
||||
DEF_GO_RUNTIME(MAPASSIGN_FAST32PTR, "runtime.mapassign_fast32ptr",
|
||||
DEF_GO_RUNTIME(MAPASSIGN_FAST32PTR, "runtime.mapassign__fast32ptr",
|
||||
P3(TYPE, MAP, POINTER), R1(POINTER))
|
||||
|
||||
// Assignment to a 64-bit pointer key in a map.
|
||||
DEF_GO_RUNTIME(MAPASSIGN_FAST64PTR, "runtime.mapassign_fast64ptr",
|
||||
DEF_GO_RUNTIME(MAPASSIGN_FAST64PTR, "runtime.mapassign__fast64ptr",
|
||||
P3(TYPE, MAP, POINTER), R1(POINTER))
|
||||
|
||||
// Assignment to a string key in a map.
|
||||
DEF_GO_RUNTIME(MAPASSIGN_FASTSTR, "runtime.mapassign_faststr",
|
||||
DEF_GO_RUNTIME(MAPASSIGN_FASTSTR, "runtime.mapassign__faststr",
|
||||
P3(TYPE, MAP, STRING), R1(POINTER))
|
||||
|
||||
// Delete a key from a map.
|
||||
DEF_GO_RUNTIME(MAPDELETE, "runtime.mapdelete", P3(TYPE, MAP, POINTER), R0())
|
||||
|
||||
// Delete a uint32 key from a map.
|
||||
DEF_GO_RUNTIME(MAPDELETE_FAST32, "runtime.mapdelete_fast32",
|
||||
DEF_GO_RUNTIME(MAPDELETE_FAST32, "runtime.mapdelete__fast32",
|
||||
P3(TYPE, MAP, UINT32), R0())
|
||||
|
||||
// Delete a uint64 key from a map.
|
||||
DEF_GO_RUNTIME(MAPDELETE_FAST64, "runtime.mapdelete_fast64",
|
||||
DEF_GO_RUNTIME(MAPDELETE_FAST64, "runtime.mapdelete__fast64",
|
||||
P3(TYPE, MAP, UINT64), R0())
|
||||
|
||||
// Delete a string key from a map.
|
||||
DEF_GO_RUNTIME(MAPDELETE_FASTSTR, "runtime.mapdelete_faststr",
|
||||
DEF_GO_RUNTIME(MAPDELETE_FASTSTR, "runtime.mapdelete__faststr",
|
||||
P3(TYPE, MAP, STRING), R0())
|
||||
|
||||
// Begin a range over a map.
|
||||
|
|
|
@ -1342,19 +1342,21 @@ Type::make_type_descriptor_var(Gogo* gogo)
|
|||
|
||||
Type* td_type = Type::make_type_descriptor_type();
|
||||
Btype* td_btype = td_type->get_backend(gogo);
|
||||
std::string name = gogo->type_descriptor_name(this, nt);
|
||||
std::string asm_name(go_selectively_encode_id(name));
|
||||
Backend_name bname;
|
||||
gogo->type_descriptor_backend_name(this, nt, &bname);
|
||||
this->type_descriptor_var_ =
|
||||
gogo->backend()->immutable_struct_reference(name, asm_name,
|
||||
td_btype,
|
||||
bloc);
|
||||
gogo->backend()->immutable_struct_reference(bname.name(),
|
||||
bname.optional_asm_name(),
|
||||
td_btype,
|
||||
bloc);
|
||||
|
||||
if (phash != NULL)
|
||||
*phash = this->type_descriptor_var_;
|
||||
return;
|
||||
}
|
||||
|
||||
std::string var_name = gogo->type_descriptor_name(this, nt);
|
||||
Backend_name bname;
|
||||
gogo->type_descriptor_backend_name(this, nt, &bname);
|
||||
|
||||
// Build the contents of the type descriptor.
|
||||
Expression* initializer = this->do_type_descriptor(gogo, NULL);
|
||||
|
@ -1366,11 +1368,11 @@ Type::make_type_descriptor_var(Gogo* gogo)
|
|||
const Package* dummy;
|
||||
if (this->type_descriptor_defined_elsewhere(nt, &dummy))
|
||||
{
|
||||
std::string asm_name(go_selectively_encode_id(var_name));
|
||||
this->type_descriptor_var_ =
|
||||
gogo->backend()->immutable_struct_reference(var_name, asm_name,
|
||||
initializer_btype,
|
||||
loc);
|
||||
gogo->backend()->immutable_struct_reference(bname.name(),
|
||||
bname.optional_asm_name(),
|
||||
initializer_btype,
|
||||
loc);
|
||||
if (phash != NULL)
|
||||
*phash = this->type_descriptor_var_;
|
||||
return;
|
||||
|
@ -1399,10 +1401,10 @@ Type::make_type_descriptor_var(Gogo* gogo)
|
|||
// ensure that type_descriptor_pointer will work if called while
|
||||
// converting INITIALIZER.
|
||||
|
||||
std::string asm_name(go_selectively_encode_id(var_name));
|
||||
this->type_descriptor_var_ =
|
||||
gogo->backend()->immutable_struct(var_name, asm_name, false, is_common,
|
||||
initializer_btype, loc);
|
||||
gogo->backend()->immutable_struct(bname.name(), bname.optional_asm_name(),
|
||||
false, is_common, initializer_btype,
|
||||
loc);
|
||||
if (phash != NULL)
|
||||
*phash = this->type_descriptor_var_;
|
||||
|
||||
|
@ -1411,7 +1413,7 @@ Type::make_type_descriptor_var(Gogo* gogo)
|
|||
Bexpression* binitializer = initializer->get_backend(&context);
|
||||
|
||||
gogo->backend()->immutable_struct_set_init(this->type_descriptor_var_,
|
||||
var_name, false, is_common,
|
||||
bname.name(), false, is_common,
|
||||
initializer_btype, loc,
|
||||
binitializer);
|
||||
|
||||
|
@ -1924,19 +1926,20 @@ Type::build_hash_function(Gogo* gogo, int64_t size, Function_type* hash_fntype)
|
|||
return ins.first->second;
|
||||
}
|
||||
|
||||
std::string hash_name = gogo->hash_function_name(type);
|
||||
Backend_name bname;
|
||||
gogo->hash_function_name(type, &bname);
|
||||
|
||||
Location bloc = Linemap::predeclared_location();
|
||||
|
||||
Named_object* hash_fn = gogo->declare_package_function(hash_name,
|
||||
Named_object* hash_fn = gogo->declare_package_function(bname.name(),
|
||||
hash_fntype, bloc);
|
||||
|
||||
ins.first->second = hash_fn;
|
||||
|
||||
if (gogo->in_global_scope())
|
||||
type->write_hash_function(gogo, size, hash_name, hash_fntype);
|
||||
type->write_hash_function(gogo, size, &bname, hash_fntype);
|
||||
else
|
||||
gogo->queue_hash_function(type, size, hash_name, hash_fntype);
|
||||
gogo->queue_hash_function(type, size, &bname, hash_fntype);
|
||||
|
||||
return hash_fn;
|
||||
}
|
||||
|
@ -1944,8 +1947,7 @@ Type::build_hash_function(Gogo* gogo, int64_t size, Function_type* hash_fntype)
|
|||
// Write the hash function for a type that needs it written specially.
|
||||
|
||||
void
|
||||
Type::write_hash_function(Gogo* gogo, int64_t size,
|
||||
const std::string& hash_name,
|
||||
Type::write_hash_function(Gogo* gogo, int64_t size, const Backend_name* bname,
|
||||
Function_type* hash_fntype)
|
||||
{
|
||||
Location bloc = Linemap::predeclared_location();
|
||||
|
@ -1958,8 +1960,9 @@ Type::write_hash_function(Gogo* gogo, int64_t size,
|
|||
|
||||
go_assert(this->is_comparable());
|
||||
|
||||
Named_object* hash_fn = gogo->start_function(hash_name, hash_fntype, false,
|
||||
bloc);
|
||||
Named_object* hash_fn = gogo->start_function(bname->name(), hash_fntype,
|
||||
false, bloc);
|
||||
hash_fn->func_value()->set_asm_name(bname->asm_name());
|
||||
hash_fn->func_value()->set_is_type_specific_function();
|
||||
gogo->start_block(bloc);
|
||||
|
||||
|
@ -2245,7 +2248,8 @@ Type::build_equal_function(Gogo* gogo, Named_type* name, int64_t size,
|
|||
return ins.first->second;
|
||||
}
|
||||
|
||||
std::string equal_name = gogo->equal_function_name(this, name);
|
||||
Backend_name bname;
|
||||
gogo->equal_function_name(this, name, &bname);
|
||||
|
||||
Location bloc = Linemap::predeclared_location();
|
||||
|
||||
|
@ -2255,19 +2259,21 @@ Type::build_equal_function(Gogo* gogo, Named_type* name, int64_t size,
|
|||
|
||||
Named_object* equal_fn;
|
||||
if (is_defined_elsewhere)
|
||||
equal_fn = Named_object::make_function_declaration(equal_name, package,
|
||||
equal_fn = Named_object::make_function_declaration(bname.name(), package,
|
||||
equal_fntype, bloc);
|
||||
else
|
||||
equal_fn = gogo->declare_package_function(equal_name, equal_fntype, bloc);
|
||||
equal_fn = gogo->declare_package_function(bname.name(), equal_fntype, bloc);
|
||||
|
||||
ins.first->second = equal_fn;
|
||||
|
||||
if (!is_defined_elsewhere)
|
||||
if (is_defined_elsewhere)
|
||||
equal_fn->func_declaration_value()->set_asm_name(bname.asm_name());
|
||||
else
|
||||
{
|
||||
if (gogo->in_global_scope())
|
||||
this->write_equal_function(gogo, name, size, equal_name, equal_fntype);
|
||||
this->write_equal_function(gogo, name, size, &bname, equal_fntype);
|
||||
else
|
||||
gogo->queue_equal_function(this, name, size, equal_name, equal_fntype);
|
||||
gogo->queue_equal_function(this, name, size, &bname, equal_fntype);
|
||||
}
|
||||
|
||||
return equal_fn;
|
||||
|
@ -2278,7 +2284,7 @@ Type::build_equal_function(Gogo* gogo, Named_type* name, int64_t size,
|
|||
|
||||
void
|
||||
Type::write_equal_function(Gogo* gogo, Named_type* name, int64_t size,
|
||||
const std::string& equal_name,
|
||||
const Backend_name* bname,
|
||||
Function_type* equal_fntype)
|
||||
{
|
||||
Location bloc = Linemap::predeclared_location();
|
||||
|
@ -2291,8 +2297,9 @@ Type::write_equal_function(Gogo* gogo, Named_type* name, int64_t size,
|
|||
|
||||
go_assert(this->is_comparable());
|
||||
|
||||
Named_object* equal_fn = gogo->start_function(equal_name, equal_fntype,
|
||||
Named_object* equal_fn = gogo->start_function(bname->name(), equal_fntype,
|
||||
false, bloc);
|
||||
equal_fn->func_value()->set_asm_name(bname->asm_name());
|
||||
equal_fn->func_value()->set_is_type_specific_function();
|
||||
gogo->start_block(bloc);
|
||||
|
||||
|
@ -2671,9 +2678,8 @@ Type::make_gc_symbol_var(Gogo* gogo)
|
|||
const Package* dummy;
|
||||
if (this->type_descriptor_defined_elsewhere(nt, &dummy))
|
||||
{
|
||||
std::string asm_name(go_selectively_encode_id(sym_name));
|
||||
this->gc_symbol_var_ =
|
||||
gogo->backend()->implicit_variable_reference(sym_name, asm_name,
|
||||
gogo->backend()->implicit_variable_reference(sym_name, "",
|
||||
sym_btype);
|
||||
if (phash != NULL)
|
||||
*phash = this->gc_symbol_var_;
|
||||
|
@ -2699,10 +2705,9 @@ Type::make_gc_symbol_var(Gogo* gogo)
|
|||
// Since we are building the GC symbol in this package, we must create the
|
||||
// variable before converting the initializer to its backend representation
|
||||
// because the initializer may refer to the GC symbol for this type.
|
||||
std::string asm_name(go_selectively_encode_id(sym_name));
|
||||
this->gc_symbol_var_ =
|
||||
gogo->backend()->implicit_variable(sym_name, asm_name,
|
||||
sym_btype, false, true, is_common, 0);
|
||||
gogo->backend()->implicit_variable(sym_name, "", sym_btype, false, true,
|
||||
is_common, 0);
|
||||
if (phash != NULL)
|
||||
*phash = this->gc_symbol_var_;
|
||||
|
||||
|
@ -2876,14 +2881,17 @@ Ptrmask::set_from(Gogo* gogo, Type* type, int64_t ptrsize, int64_t offset)
|
|||
}
|
||||
}
|
||||
|
||||
// Return a symbol name for this ptrmask. This is used to coalesce identical
|
||||
// ptrmasks, which are common. The symbol name must use only characters that are
|
||||
// valid in symbols. It's nice if it's short. For smaller ptrmasks, we convert
|
||||
// it to a string that uses only 32 characters, avoiding digits and u and U. For
|
||||
// longer pointer masks, apply the same process to the SHA1 digest of the bits,
|
||||
// so as to avoid pathologically long symbol names (see related Go issues #32083
|
||||
// and #11583 for more on this). To avoid collisions between the two encoding
|
||||
// schemes, use a prefix ("X") for the SHA form to disambiguate.
|
||||
// Return a symbol name for this ptrmask. This is used to coalesce
|
||||
// identical ptrmasks, which are common. The symbol name must use
|
||||
// only characters that are valid in symbols. It's nice if it's
|
||||
// short. For smaller ptrmasks, we convert it to a string that uses
|
||||
// only 32 characters. For longer pointer masks, apply the same
|
||||
// process to the SHA1 digest of the bits, so as to avoid
|
||||
// pathologically long symbol names (see related Go issues #32083 and
|
||||
// #11583 for more on this). To avoid collisions between the two
|
||||
// encoding schemes, use a prefix ("X") for the SHA form to
|
||||
// disambiguate.
|
||||
|
||||
std::string
|
||||
Ptrmask::symname() const
|
||||
{
|
||||
|
@ -2911,7 +2919,7 @@ Ptrmask::symname() const
|
|||
bits = &shabits;
|
||||
}
|
||||
|
||||
const char chars[33] = "abcdefghijklmnopqrstvwxyzABCDEFG";
|
||||
const char chars[33] = "abcdefghijklmnopqrstuvwxyzABCDEF";
|
||||
go_assert(chars[32] == '\0');
|
||||
std::string ret(prefix);
|
||||
unsigned int b = 0;
|
||||
|
@ -2995,9 +3003,8 @@ Type::gc_ptrmask_var(Gogo* gogo, int64_t ptrsize, int64_t ptrdata)
|
|||
context.set_is_const();
|
||||
Bexpression* bval = val->get_backend(&context);
|
||||
|
||||
std::string asm_name(go_selectively_encode_id(sym_name));
|
||||
Btype *btype = val->type()->get_backend(gogo);
|
||||
Bvariable* ret = gogo->backend()->implicit_variable(sym_name, asm_name,
|
||||
Bvariable* ret = gogo->backend()->implicit_variable(sym_name, "",
|
||||
btype, false, true,
|
||||
true, 0);
|
||||
gogo->backend()->implicit_variable_set_init(ret, sym_name, btype, false,
|
||||
|
@ -8092,11 +8099,9 @@ Map_type::backend_zero_value(Gogo* gogo)
|
|||
Btype* barray_type = gogo->backend()->array_type(buint8_type, blength);
|
||||
|
||||
std::string zname = Map_type::zero_value->name();
|
||||
std::string asm_name(go_selectively_encode_id(zname));
|
||||
Bvariable* zvar =
|
||||
gogo->backend()->implicit_variable(zname, asm_name,
|
||||
barray_type, false, false, true,
|
||||
Map_type::zero_value_align);
|
||||
gogo->backend()->implicit_variable(zname, "", barray_type, false, false,
|
||||
true, Map_type::zero_value_align);
|
||||
gogo->backend()->implicit_variable_set_init(zvar, zname, barray_type,
|
||||
false, false, true, NULL);
|
||||
return zvar;
|
||||
|
|
|
@ -49,6 +49,7 @@ class Function;
|
|||
class Translate_context;
|
||||
class Export;
|
||||
class Import;
|
||||
class Backend_name;
|
||||
class Btype;
|
||||
class Bexpression;
|
||||
class Bvariable;
|
||||
|
@ -1008,11 +1009,11 @@ class Type
|
|||
std::string
|
||||
reflection(Gogo*) const;
|
||||
|
||||
// Return a mangled name for the type. This is a name which can be
|
||||
// used in assembler code. Identical types should have the same
|
||||
// manged name.
|
||||
std::string
|
||||
mangled_name(Gogo*) const;
|
||||
// Add the backend name for the type to BNAME. This will add one or
|
||||
// two name components. Identical types should have the same
|
||||
// backend name.
|
||||
void
|
||||
backend_name(Gogo*, Backend_name* bname) const;
|
||||
|
||||
// If the size of the type can be determined, set *PSIZE to the size
|
||||
// in bytes and return true. Otherwise, return false. This queries
|
||||
|
@ -1066,12 +1067,11 @@ class Type
|
|||
// Write the equal function for a type.
|
||||
void
|
||||
write_equal_function(Gogo*, Named_type*, int64_t size,
|
||||
const std::string& equal_name,
|
||||
Function_type* equal_fntype);
|
||||
const Backend_name*, Function_type* equal_fntype);
|
||||
|
||||
// Write the hash function for a type.
|
||||
void
|
||||
write_hash_function(Gogo*, int64_t size, const std::string& hash_name,
|
||||
write_hash_function(Gogo*, int64_t size, const Backend_name*,
|
||||
Function_type* hash_fntype);
|
||||
|
||||
// Return the alignment required by the memequalN function.
|
||||
|
@ -3557,10 +3557,10 @@ class Named_type : public Type
|
|||
void
|
||||
append_reflection_type_name(Gogo*, bool use_alias, std::string*) const;
|
||||
|
||||
// Append the mangled type name as for Type::append_mangled_name,
|
||||
// Append the symbol type name as for Type::append_mangled_name,
|
||||
// but if USE_ALIAS use the alias name rather than the alias target.
|
||||
void
|
||||
append_mangled_type_name(Gogo*, bool use_alias, std::string*) const;
|
||||
append_symbol_type_name(Gogo*, bool use_alias, std::string*) const;
|
||||
|
||||
// Import a named type.
|
||||
static void
|
||||
|
|
2
libgo/configure
vendored
2
libgo/configure
vendored
|
@ -2551,7 +2551,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
|||
ac_config_headers="$ac_config_headers config.h"
|
||||
|
||||
|
||||
libtool_VERSION=17:0:0
|
||||
libtool_VERSION=18:0:0
|
||||
|
||||
|
||||
# Default to --enable-multilib
|
||||
|
|
|
@ -10,7 +10,7 @@ AC_INIT(package-unused, version-unused,, libgo)
|
|||
AC_CONFIG_SRCDIR(Makefile.am)
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
|
||||
libtool_VERSION=17:0:0
|
||||
libtool_VERSION=18:0:0
|
||||
AC_SUBST(libtool_VERSION)
|
||||
|
||||
AM_ENABLE_MULTILIB(, ..)
|
||||
|
|
|
@ -191,7 +191,7 @@ func (p *Package) writeDefs() {
|
|||
panic(fmt.Errorf("invalid var kind %q", n.Kind))
|
||||
}
|
||||
if *gccgo {
|
||||
fmt.Fprintf(fc, `extern void *%s __asm__("%s.%s");`, n.Mangle, gccgoSymbolPrefix, n.Mangle)
|
||||
fmt.Fprintf(fc, `extern void *%s __asm__("%s.%s");`, n.Mangle, gccgoSymbolPrefix, gccgoToSymbol(n.Mangle))
|
||||
fmt.Fprintf(&gccgoInit, "\t%s = &%s;\n", n.Mangle, n.C)
|
||||
fmt.Fprintf(fc, "\n")
|
||||
}
|
||||
|
@ -1168,7 +1168,7 @@ func (p *Package) writeGccgoExports(fgo2, fm, fgcc, fgcch io.Writer) {
|
|||
// will not be able to link against it from the C
|
||||
// code.
|
||||
goName := "Cgoexp_" + exp.ExpName
|
||||
fmt.Fprintf(fgcc, `extern %s %s %s __asm__("%s.%s");`, cRet, goName, cParams, gccgoSymbolPrefix, goName)
|
||||
fmt.Fprintf(fgcc, `extern %s %s %s __asm__("%s.%s");`, cRet, goName, cParams, gccgoSymbolPrefix, gccgoToSymbol(goName))
|
||||
fmt.Fprint(fgcc, "\n")
|
||||
|
||||
fmt.Fprint(fgcc, "\nCGO_NO_SANITIZE_THREAD\n")
|
||||
|
@ -1202,7 +1202,7 @@ func (p *Package) writeGccgoExports(fgo2, fm, fgcc, fgcch io.Writer) {
|
|||
fmt.Fprint(fgcc, "}\n")
|
||||
|
||||
// Dummy declaration for _cgo_main.c
|
||||
fmt.Fprintf(fm, `char %s[1] __asm__("%s.%s");`, goName, gccgoSymbolPrefix, goName)
|
||||
fmt.Fprintf(fm, `char %s[1] __asm__("%s.%s");`, goName, gccgoSymbolPrefix, gccgoToSymbol(goName))
|
||||
fmt.Fprint(fm, "\n")
|
||||
|
||||
// For gccgo we use a wrapper function in Go, in order
|
||||
|
@ -1286,9 +1286,8 @@ func (p *Package) writeExportHeader(fgcch io.Writer) {
|
|||
fmt.Fprintf(fgcch, "%s\n", p.gccExportHeaderProlog())
|
||||
}
|
||||
|
||||
// gccgoPkgpathToSymbol converts a package path to a mangled packagepath
|
||||
// symbol.
|
||||
func gccgoPkgpathToSymbol(ppath string) string {
|
||||
// gccgoToSymbol converts a name to a mangled symbol for gccgo.
|
||||
func gccgoToSymbol(ppath string) string {
|
||||
if gccgoMangler == nil {
|
||||
var err error
|
||||
cmd := os.Getenv("GCCGO")
|
||||
|
@ -1313,12 +1312,12 @@ func (p *Package) gccgoSymbolPrefix() string {
|
|||
}
|
||||
|
||||
if *gccgopkgpath != "" {
|
||||
return gccgoPkgpathToSymbol(*gccgopkgpath)
|
||||
return gccgoToSymbol(*gccgopkgpath)
|
||||
}
|
||||
if *gccgoprefix == "" && p.PackageName == "main" {
|
||||
return "main"
|
||||
}
|
||||
prefix := gccgoPkgpathToSymbol(*gccgoprefix)
|
||||
prefix := gccgoToSymbol(*gccgoprefix)
|
||||
if prefix == "" {
|
||||
prefix = "go"
|
||||
}
|
||||
|
@ -1710,8 +1709,12 @@ void _cgoPREFIX_Cfunc__Cmalloc(void *v) {
|
|||
`
|
||||
|
||||
func (p *Package) cPrologGccgo() string {
|
||||
return strings.Replace(strings.Replace(cPrologGccgo, "PREFIX", cPrefix, -1),
|
||||
"GCCGOSYMBOLPREF", p.gccgoSymbolPrefix(), -1)
|
||||
r := strings.NewReplacer(
|
||||
"PREFIX", cPrefix,
|
||||
"GCCGOSYMBOLPREF", p.gccgoSymbolPrefix(),
|
||||
"_cgoCheckPointer", gccgoToSymbol("_cgoCheckPointer"),
|
||||
"_cgoCheckResult", gccgoToSymbol("_cgoCheckResult"))
|
||||
return r.Replace(cPrologGccgo)
|
||||
}
|
||||
|
||||
const cPrologGccgo = `
|
||||
|
|
|
@ -50,9 +50,12 @@ func ToSymbolFunc(cmd, tmpdir string) (func(string) string, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// New mangling: expect go.l..u00e4ufer.Run
|
||||
// Old mangling: expect go.l__ufer.Run
|
||||
if bytes.Contains(buf, []byte("go.l..u00e4ufer.Run")) {
|
||||
// Original mangling: go.l__ufer.Run
|
||||
// Mangling v2: go.l..u00e4ufer.Run
|
||||
// Mangling v3: go_0l_u00e4ufer.Run
|
||||
if bytes.Contains(buf, []byte("go_0l_u00e4ufer.Run")) {
|
||||
return toSymbolV3, nil
|
||||
} else if bytes.Contains(buf, []byte("go.l..u00e4ufer.Run")) {
|
||||
return toSymbolV2, nil
|
||||
} else if bytes.Contains(buf, []byte("go.l__ufer.Run")) {
|
||||
return toSymbolV1, nil
|
||||
|
@ -82,7 +85,7 @@ func toSymbolV1(ppath string) string {
|
|||
return strings.Map(clean, ppath)
|
||||
}
|
||||
|
||||
// toSymbolV2 converts a package path using the newer mangling scheme.
|
||||
// toSymbolV2 converts a package path using the second mangling scheme.
|
||||
func toSymbolV2(ppath string) string {
|
||||
// This has to build at boostrap time, so it has to build
|
||||
// with Go 1.4, so we don't use strings.Builder.
|
||||
|
@ -112,3 +115,60 @@ func toSymbolV2(ppath string) string {
|
|||
}
|
||||
return string(bsl)
|
||||
}
|
||||
|
||||
// v3UnderscoreCodes maps from a character that supports an underscore
|
||||
// encoding to the underscore encoding character.
|
||||
var v3UnderscoreCodes = map[byte]byte{
|
||||
'_': '_',
|
||||
'.': '0',
|
||||
'/': '1',
|
||||
'*': '2',
|
||||
',': '3',
|
||||
'{': '4',
|
||||
'}': '5',
|
||||
'[': '6',
|
||||
']': '7',
|
||||
'(': '8',
|
||||
')': '9',
|
||||
'"': 'a',
|
||||
' ': 'b',
|
||||
';': 'c',
|
||||
}
|
||||
|
||||
// toSymbolV3 converts a package path using the third mangling scheme.
|
||||
func toSymbolV3(ppath string) string {
|
||||
// This has to build at boostrap time, so it has to build
|
||||
// with Go 1.4, so we don't use strings.Builder.
|
||||
bsl := make([]byte, 0, len(ppath))
|
||||
changed := false
|
||||
for _, c := range ppath {
|
||||
if ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || ('0' <= c && c <= '9') {
|
||||
bsl = append(bsl, byte(c))
|
||||
continue
|
||||
}
|
||||
|
||||
if c < 0x80 {
|
||||
if u, ok := v3UnderscoreCodes[byte(c)]; ok {
|
||||
bsl = append(bsl, '_', u)
|
||||
changed = true
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
var enc string
|
||||
switch {
|
||||
case c < 0x80:
|
||||
enc = fmt.Sprintf("_x%02x", c)
|
||||
case c < 0x10000:
|
||||
enc = fmt.Sprintf("_u%04x", c)
|
||||
default:
|
||||
enc = fmt.Sprintf("_U%08x", c)
|
||||
}
|
||||
bsl = append(bsl, enc...)
|
||||
changed = true
|
||||
}
|
||||
if !changed {
|
||||
return ppath
|
||||
}
|
||||
return string(bsl)
|
||||
}
|
||||
|
|
|
@ -24,6 +24,9 @@ func init() {
|
|||
case "v2":
|
||||
os.Stdout.WriteString(`.string "go.l..u00e4ufer.Run"`)
|
||||
os.Exit(0)
|
||||
case "v3":
|
||||
os.Stdout.WriteString(`.string "go_0l_u00e4ufer.Run"`)
|
||||
os.Exit(0)
|
||||
case "error":
|
||||
os.Stdout.WriteString(`unknown string`)
|
||||
os.Exit(0)
|
||||
|
@ -45,6 +48,10 @@ func TestToSymbolFunc(t *testing.T) {
|
|||
env: "v2",
|
||||
mangled: "p..u00e4..u4e16..U0001f703",
|
||||
},
|
||||
{
|
||||
env: "v3",
|
||||
mangled: "p_u00e4_u4e16_U0001f703",
|
||||
},
|
||||
{
|
||||
env: "error",
|
||||
fail: true,
|
||||
|
@ -75,32 +82,37 @@ func TestToSymbolFunc(t *testing.T) {
|
|||
}
|
||||
|
||||
var symbolTests = []struct {
|
||||
input, v1, v2 string
|
||||
input, v1, v2, v3 string
|
||||
}{
|
||||
{
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
},
|
||||
{
|
||||
"bytes",
|
||||
"bytes",
|
||||
"bytes",
|
||||
"bytes",
|
||||
},
|
||||
{
|
||||
"net/http",
|
||||
"net_http",
|
||||
"net..z2fhttp",
|
||||
"net_1http",
|
||||
},
|
||||
{
|
||||
"golang.org/x/net/http",
|
||||
"golang_org_x_net_http",
|
||||
"golang.x2eorg..z2fx..z2fnet..z2fhttp",
|
||||
"golang_0org_1x_1net_1http",
|
||||
},
|
||||
{
|
||||
"pä世.🜃",
|
||||
"p____",
|
||||
"p..u00e4..u4e16.x2e..U0001f703",
|
||||
"p_u00e4_u4e16_0_U0001f703",
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -119,3 +131,11 @@ func TestV2(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestV3(t *testing.T) {
|
||||
for _, test := range symbolTests {
|
||||
if got, want := toSymbolV3(test.input), test.v3; got != want {
|
||||
t.Errorf("toSymbolV3(%q) = %q, want %q", test.input, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -262,5 +262,5 @@ func (p *Importer) joinPath(elem ...string) string {
|
|||
return filepath.Join(elem...)
|
||||
}
|
||||
|
||||
//go:linkname setUsesCgo go/types.srcimporter_setUsesCgo
|
||||
//go:linkname setUsesCgo go_1types.srcimporter__setUsesCgo
|
||||
func setUsesCgo(conf *types.Config)
|
||||
|
|
|
@ -38,7 +38,7 @@ static const void *goMemmem(const void *in, size_t inl, const void *s, size_t sl
|
|||
#endif
|
||||
|
||||
intgo Compare(struct __go_open_array, struct __go_open_array)
|
||||
__asm__(GOSYM_PREFIX "internal..z2fbytealg.Compare")
|
||||
__asm__(GOSYM_PREFIX "internal_1bytealg.Compare")
|
||||
__attribute__((no_split_stack));
|
||||
|
||||
intgo Compare(struct __go_open_array a, struct __go_open_array b)
|
||||
|
@ -69,7 +69,7 @@ intgo Compare(struct __go_open_array a, struct __go_open_array b)
|
|||
}
|
||||
|
||||
intgo IndexByte(struct __go_open_array, byte)
|
||||
__asm__(GOSYM_PREFIX "internal..z2fbytealg.IndexByte")
|
||||
__asm__(GOSYM_PREFIX "internal_1bytealg.IndexByte")
|
||||
__attribute__((no_split_stack));
|
||||
|
||||
intgo IndexByte(struct __go_open_array b, byte c)
|
||||
|
@ -85,7 +85,7 @@ intgo IndexByte(struct __go_open_array b, byte c)
|
|||
|
||||
|
||||
intgo IndexByteString(String, byte)
|
||||
__asm__(GOSYM_PREFIX "internal..z2fbytealg.IndexByteString")
|
||||
__asm__(GOSYM_PREFIX "internal_1bytealg.IndexByteString")
|
||||
__attribute__((no_split_stack));
|
||||
|
||||
intgo IndexByteString(String s, byte c)
|
||||
|
@ -100,7 +100,7 @@ intgo IndexByteString(String s, byte c)
|
|||
}
|
||||
|
||||
intgo Index(struct __go_open_array, struct __go_open_array)
|
||||
__asm__(GOSYM_PREFIX "internal..z2fbytealg.Index")
|
||||
__asm__(GOSYM_PREFIX "internal_1bytealg.Index")
|
||||
__attribute__((no_split_stack));
|
||||
|
||||
intgo Index(struct __go_open_array a, struct __go_open_array b)
|
||||
|
@ -115,7 +115,7 @@ intgo Index(struct __go_open_array a, struct __go_open_array b)
|
|||
}
|
||||
|
||||
intgo IndexString(String, String)
|
||||
__asm__(GOSYM_PREFIX "internal..z2fbytealg.IndexString")
|
||||
__asm__(GOSYM_PREFIX "internal_1bytealg.IndexString")
|
||||
__attribute__((no_split_stack));
|
||||
|
||||
intgo IndexString(String a, String b)
|
||||
|
|
|
@ -21,7 +21,7 @@ struct cpuid_ret {
|
|||
};
|
||||
|
||||
struct cpuid_ret cpuid(uint32_t, uint32_t)
|
||||
__asm__(GOSYM_PREFIX "internal..z2fcpu.cpuid")
|
||||
__asm__(GOSYM_PREFIX "internal_1cpu.cpuid")
|
||||
__attribute__((no_split_stack));
|
||||
|
||||
struct cpuid_ret cpuid(uint32_t eaxArg, uint32_t ecxArg) {
|
||||
|
@ -45,7 +45,7 @@ struct xgetbv_ret {
|
|||
};
|
||||
|
||||
struct xgetbv_ret xgetbv(void)
|
||||
__asm__(GOSYM_PREFIX "internal..z2fcpu.xgetbv")
|
||||
__asm__(GOSYM_PREFIX "internal_1cpu.xgetbv")
|
||||
__attribute__((no_split_stack));
|
||||
|
||||
#pragma GCC push_options
|
||||
|
@ -82,7 +82,7 @@ struct queryResult {
|
|||
};
|
||||
|
||||
struct facilityList stfle(void)
|
||||
__asm__(GOSYM_PREFIX "internal..z2fcpu.stfle")
|
||||
__asm__(GOSYM_PREFIX "internal_1cpu.stfle")
|
||||
__attribute__((no_split_stack));
|
||||
|
||||
struct facilityList stfle(void) {
|
||||
|
@ -96,7 +96,7 @@ struct facilityList stfle(void) {
|
|||
}
|
||||
|
||||
struct queryResult kmQuery(void)
|
||||
__asm__(GOSYM_PREFIX "internal..z2fcpu.kmQuery")
|
||||
__asm__(GOSYM_PREFIX "internal_1cpu.kmQuery")
|
||||
__attribute__((no_split_stack));
|
||||
|
||||
struct queryResult kmQuery() {
|
||||
|
@ -110,7 +110,7 @@ struct queryResult kmQuery() {
|
|||
}
|
||||
|
||||
struct queryResult kmcQuery(void)
|
||||
__asm__(GOSYM_PREFIX "internal..z2fcpu.kmcQuery")
|
||||
__asm__(GOSYM_PREFIX "internal_1cpu.kmcQuery")
|
||||
__attribute__((no_split_stack));
|
||||
|
||||
struct queryResult kmcQuery() {
|
||||
|
@ -125,7 +125,7 @@ struct queryResult kmcQuery() {
|
|||
}
|
||||
|
||||
struct queryResult kmctrQuery(void)
|
||||
__asm__(GOSYM_PREFIX "internal..z2fcpu.kmctrQuery")
|
||||
__asm__(GOSYM_PREFIX "internal_1cpu.kmctrQuery")
|
||||
__attribute__((no_split_stack));
|
||||
|
||||
struct queryResult kmctrQuery() {
|
||||
|
@ -140,7 +140,7 @@ struct queryResult kmctrQuery() {
|
|||
}
|
||||
|
||||
struct queryResult kmaQuery(void)
|
||||
__asm__(GOSYM_PREFIX "internal..z2fcpu.kmaQuery")
|
||||
__asm__(GOSYM_PREFIX "internal_1cpu.kmaQuery")
|
||||
__attribute__((no_split_stack));
|
||||
|
||||
struct queryResult kmaQuery() {
|
||||
|
@ -155,7 +155,7 @@ struct queryResult kmaQuery() {
|
|||
}
|
||||
|
||||
struct queryResult kimdQuery(void)
|
||||
__asm__(GOSYM_PREFIX "internal..z2fcpu.kimdQuery")
|
||||
__asm__(GOSYM_PREFIX "internal_1cpu.kimdQuery")
|
||||
__attribute__((no_split_stack));
|
||||
|
||||
struct queryResult kimdQuery() {
|
||||
|
@ -170,7 +170,7 @@ struct queryResult kimdQuery() {
|
|||
}
|
||||
|
||||
struct queryResult klmdQuery(void)
|
||||
__asm__(GOSYM_PREFIX "internal..z2fcpu.klmdQuery")
|
||||
__asm__(GOSYM_PREFIX "internal_1cpu.klmdQuery")
|
||||
__attribute__((no_split_stack));
|
||||
|
||||
struct queryResult klmdQuery() {
|
||||
|
@ -185,7 +185,7 @@ struct queryResult klmdQuery() {
|
|||
}
|
||||
|
||||
struct queryResult kdsaQuery(void)
|
||||
__asm__(GOSYM_PREFIX "internal..z2fcpu.kdsaQuery")
|
||||
__asm__(GOSYM_PREFIX "internal_1cpu.kdsaQuery")
|
||||
__attribute__((no_split_stack));
|
||||
|
||||
struct queryResult kdsaQuery() {
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
can't represent a C varargs function in Go. */
|
||||
|
||||
void syslog_c(intgo, const char*)
|
||||
__asm__ (GOSYM_PREFIX "log..z2fsyslog.syslog_c");
|
||||
__asm__ (GOSYM_PREFIX "log_1syslog.syslog_c");
|
||||
|
||||
void
|
||||
syslog_c (intgo priority, const char *msg)
|
||||
|
|
|
@ -39,10 +39,10 @@ func atomicstorep(ptr unsafe.Pointer, new unsafe.Pointer) {
|
|||
// We cannot just call the runtime routines, because the race detector expects
|
||||
// to be able to intercept the sync/atomic forms but not the runtime forms.
|
||||
|
||||
//go:linkname sync_atomic_StoreUintptr sync..z2fatomic.StoreUintptr
|
||||
//go:linkname sync_atomic_StoreUintptr sync_1atomic.StoreUintptr
|
||||
func sync_atomic_StoreUintptr(ptr *uintptr, new uintptr)
|
||||
|
||||
//go:linkname sync_atomic_StorePointer sync..z2fatomic.StorePointer
|
||||
//go:linkname sync_atomic_StorePointer sync_1atomic.StorePointer
|
||||
//go:nosplit
|
||||
func sync_atomic_StorePointer(ptr *unsafe.Pointer, new unsafe.Pointer) {
|
||||
if writeBarrier.enabled {
|
||||
|
@ -51,10 +51,10 @@ func sync_atomic_StorePointer(ptr *unsafe.Pointer, new unsafe.Pointer) {
|
|||
sync_atomic_StoreUintptr((*uintptr)(unsafe.Pointer(ptr)), uintptr(new))
|
||||
}
|
||||
|
||||
//go:linkname sync_atomic_SwapUintptr sync..z2fatomic.SwapUintptr
|
||||
//go:linkname sync_atomic_SwapUintptr sync_1atomic.SwapUintptr
|
||||
func sync_atomic_SwapUintptr(ptr *uintptr, new uintptr) uintptr
|
||||
|
||||
//go:linkname sync_atomic_SwapPointer sync..z2fatomic.SwapPointer
|
||||
//go:linkname sync_atomic_SwapPointer sync_1atomic.SwapPointer
|
||||
//go:nosplit
|
||||
func sync_atomic_SwapPointer(ptr *unsafe.Pointer, new unsafe.Pointer) unsafe.Pointer {
|
||||
if writeBarrier.enabled {
|
||||
|
@ -64,10 +64,10 @@ func sync_atomic_SwapPointer(ptr *unsafe.Pointer, new unsafe.Pointer) unsafe.Poi
|
|||
return old
|
||||
}
|
||||
|
||||
//go:linkname sync_atomic_CompareAndSwapUintptr sync..z2fatomic.CompareAndSwapUintptr
|
||||
//go:linkname sync_atomic_CompareAndSwapUintptr sync_1atomic.CompareAndSwapUintptr
|
||||
func sync_atomic_CompareAndSwapUintptr(ptr *uintptr, old, new uintptr) bool
|
||||
|
||||
//go:linkname sync_atomic_CompareAndSwapPointer sync..z2fatomic.CompareAndSwapPointer
|
||||
//go:linkname sync_atomic_CompareAndSwapPointer sync_1atomic.CompareAndSwapPointer
|
||||
//go:nosplit
|
||||
func sync_atomic_CompareAndSwapPointer(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool {
|
||||
if writeBarrier.enabled {
|
||||
|
|
|
@ -774,7 +774,7 @@ func reflect_chanlen(c *hchan) int {
|
|||
return int(c.qcount)
|
||||
}
|
||||
|
||||
//go:linkname reflectlite_chanlen internal..z2freflectlite.chanlen
|
||||
//go:linkname reflectlite_chanlen internal_1reflectlite.chanlen
|
||||
func reflectlite_chanlen(c *hchan) int {
|
||||
if c == nil {
|
||||
return 0
|
||||
|
|
|
@ -189,7 +189,7 @@ func CPUProfile() []byte {
|
|||
panic("CPUProfile no longer available")
|
||||
}
|
||||
|
||||
//go:linkname runtime_pprof_runtime_cyclesPerSecond runtime..z2fpprof.runtime_cyclesPerSecond
|
||||
//go:linkname runtime_pprof_runtime_cyclesPerSecond runtime_1pprof.runtime__cyclesPerSecond
|
||||
func runtime_pprof_runtime_cyclesPerSecond() int64 {
|
||||
return tickspersecond()
|
||||
}
|
||||
|
@ -200,7 +200,7 @@ func runtime_pprof_runtime_cyclesPerSecond() int64 {
|
|||
// on has been returned, readProfile returns eof=true.
|
||||
// The caller must save the returned data and tags before calling readProfile again.
|
||||
//
|
||||
//go:linkname runtime_pprof_readProfile runtime..z2fpprof.readProfile
|
||||
//go:linkname runtime_pprof_readProfile runtime_1pprof.readProfile
|
||||
func runtime_pprof_readProfile() ([]uint64, []unsafe.Pointer, bool) {
|
||||
lock(&cpuprof.lock)
|
||||
log := cpuprof.log
|
||||
|
|
|
@ -66,7 +66,7 @@ func NumGoroutine() int {
|
|||
// added.
|
||||
func Fieldtrack(map[string]bool)
|
||||
|
||||
//go:linkname debug_modinfo runtime..z2fdebug.modinfo
|
||||
//go:linkname debug_modinfo runtime_1debug.modinfo
|
||||
func debug_modinfo() string {
|
||||
return modinfo
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ import (
|
|||
"unsafe"
|
||||
)
|
||||
|
||||
//go:linkname runtime_debug_WriteHeapDump runtime..z2fdebug.WriteHeapDump
|
||||
//go:linkname runtime_debug_WriteHeapDump runtime_1debug.WriteHeapDump
|
||||
func runtime_debug_WriteHeapDump(fd uintptr) {
|
||||
stopTheWorld("write heap dump")
|
||||
|
||||
|
|
|
@ -505,7 +505,7 @@ func reflect_ifaceE2I(inter *interfacetype, e eface, dst *iface) {
|
|||
dst.data = e.data
|
||||
}
|
||||
|
||||
//go:linkname reflectlite_ifaceE2I internal..z2freflectlite.ifaceE2I
|
||||
//go:linkname reflectlite_ifaceE2I internal_1reflectlite.ifaceE2I
|
||||
func reflectlite_ifaceE2I(inter *interfacetype, e eface, dst *iface) {
|
||||
t := e._type
|
||||
if t == nil {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include "runtime.h"
|
||||
|
||||
uint32_t Load (uint32_t *ptr)
|
||||
__asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Load")
|
||||
__asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Load")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
uint32_t
|
||||
|
@ -17,7 +17,7 @@ Load (uint32_t *ptr)
|
|||
}
|
||||
|
||||
void *Loadp (void *ptr)
|
||||
__asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Loadp")
|
||||
__asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Loadp")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
void *
|
||||
|
@ -27,7 +27,7 @@ Loadp (void *ptr)
|
|||
}
|
||||
|
||||
uint8_t Load8 (uint8_t *ptr)
|
||||
__asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Load8")
|
||||
__asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Load8")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
uint8_t
|
||||
|
@ -37,7 +37,7 @@ Load8 (uint8_t *ptr)
|
|||
}
|
||||
|
||||
uint64_t Load64 (uint64_t *ptr)
|
||||
__asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Load64")
|
||||
__asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Load64")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
uint64_t
|
||||
|
@ -49,7 +49,7 @@ Load64 (uint64_t *ptr)
|
|||
}
|
||||
|
||||
uint32_t LoadAcq (uint32_t *ptr)
|
||||
__asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.LoadAcq")
|
||||
__asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.LoadAcq")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
uint32_t
|
||||
|
@ -59,7 +59,7 @@ LoadAcq (uint32_t *ptr)
|
|||
}
|
||||
|
||||
uintptr_t Loaduintptr (uintptr_t *ptr)
|
||||
__asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Loaduintptr")
|
||||
__asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Loaduintptr")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
uintptr_t
|
||||
|
@ -69,7 +69,7 @@ Loaduintptr (uintptr_t *ptr)
|
|||
}
|
||||
|
||||
uintgo Loaduint (uintgo *ptr)
|
||||
__asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Loaduint")
|
||||
__asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Loaduint")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
uintgo
|
||||
|
@ -79,7 +79,7 @@ Loaduint (uintgo *ptr)
|
|||
}
|
||||
|
||||
int64_t Loadint64 (int64_t *ptr)
|
||||
__asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Loadint64")
|
||||
__asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Loadint64")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
int64_t
|
||||
|
@ -91,7 +91,7 @@ Loadint64 (int64_t *ptr)
|
|||
}
|
||||
|
||||
uint32_t Xadd (uint32_t *ptr, int32_t delta)
|
||||
__asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Xadd")
|
||||
__asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Xadd")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
uint32_t
|
||||
|
@ -101,7 +101,7 @@ Xadd (uint32_t *ptr, int32_t delta)
|
|||
}
|
||||
|
||||
uint64_t Xadd64 (uint64_t *ptr, int64_t delta)
|
||||
__asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Xadd64")
|
||||
__asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Xadd64")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
uint64_t
|
||||
|
@ -113,7 +113,7 @@ Xadd64 (uint64_t *ptr, int64_t delta)
|
|||
}
|
||||
|
||||
uintptr_t Xadduintptr (uintptr_t *ptr, uintptr_t delta)
|
||||
__asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Xadduintptr")
|
||||
__asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Xadduintptr")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
uintptr_t
|
||||
|
@ -123,7 +123,7 @@ Xadduintptr (uintptr_t *ptr, uintptr_t delta)
|
|||
}
|
||||
|
||||
int64_t Xaddint64 (int64_t *ptr, int64_t delta)
|
||||
__asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Xaddint64")
|
||||
__asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Xaddint64")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
int64_t
|
||||
|
@ -135,7 +135,7 @@ Xaddint64 (int64_t *ptr, int64_t delta)
|
|||
}
|
||||
|
||||
uint32_t Xchg (uint32_t *ptr, uint32_t new)
|
||||
__asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Xchg")
|
||||
__asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Xchg")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
uint32_t
|
||||
|
@ -145,7 +145,7 @@ Xchg (uint32_t *ptr, uint32_t new)
|
|||
}
|
||||
|
||||
uint64_t Xchg64 (uint64_t *ptr, uint64_t new)
|
||||
__asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Xchg64")
|
||||
__asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Xchg64")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
uint64_t
|
||||
|
@ -157,7 +157,7 @@ Xchg64 (uint64_t *ptr, uint64_t new)
|
|||
}
|
||||
|
||||
uintptr_t Xchguintptr (uintptr_t *ptr, uintptr_t new)
|
||||
__asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Xchguintptr")
|
||||
__asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Xchguintptr")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
uintptr_t
|
||||
|
@ -167,7 +167,7 @@ Xchguintptr (uintptr_t *ptr, uintptr_t new)
|
|||
}
|
||||
|
||||
void And8 (uint8_t *ptr, uint8_t val)
|
||||
__asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.And8")
|
||||
__asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.And8")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
void
|
||||
|
@ -177,7 +177,7 @@ And8 (uint8_t *ptr, uint8_t val)
|
|||
}
|
||||
|
||||
void Or8 (uint8_t *ptr, uint8_t val)
|
||||
__asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Or8")
|
||||
__asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Or8")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
void
|
||||
|
@ -187,7 +187,7 @@ Or8 (uint8_t *ptr, uint8_t val)
|
|||
}
|
||||
|
||||
_Bool Cas (uint32_t *ptr, uint32_t old, uint32_t new)
|
||||
__asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Cas")
|
||||
__asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Cas")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
_Bool
|
||||
|
@ -197,7 +197,7 @@ Cas (uint32_t *ptr, uint32_t old, uint32_t new)
|
|||
}
|
||||
|
||||
_Bool Cas64 (uint64_t *ptr, uint64_t old, uint64_t new)
|
||||
__asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Cas64")
|
||||
__asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Cas64")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
_Bool
|
||||
|
@ -209,7 +209,7 @@ Cas64 (uint64_t *ptr, uint64_t old, uint64_t new)
|
|||
}
|
||||
|
||||
_Bool CasRel (uint32_t *ptr, uint32_t old, uint32_t new)
|
||||
__asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.CasRel")
|
||||
__asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.CasRel")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
_Bool
|
||||
|
@ -219,7 +219,7 @@ CasRel (uint32_t *ptr, uint32_t old, uint32_t new)
|
|||
}
|
||||
|
||||
_Bool Casp1 (void **ptr, void *old, void *new)
|
||||
__asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Casp1")
|
||||
__asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Casp1")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
_Bool
|
||||
|
@ -229,7 +229,7 @@ Casp1 (void **ptr, void *old, void *new)
|
|||
}
|
||||
|
||||
_Bool Casuintptr (uintptr_t *ptr, uintptr_t old, uintptr_t new)
|
||||
__asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Casuintptr")
|
||||
__asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Casuintptr")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
_Bool
|
||||
|
@ -239,7 +239,7 @@ Casuintptr (uintptr_t *ptr, uintptr_t old, uintptr_t new)
|
|||
}
|
||||
|
||||
void Store (uint32_t *ptr, uint32_t val)
|
||||
__asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Store")
|
||||
__asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Store")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
void
|
||||
|
@ -249,7 +249,7 @@ Store (uint32_t *ptr, uint32_t val)
|
|||
}
|
||||
|
||||
void Store8 (uint8_t *ptr, uint8_t val)
|
||||
__asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Store8")
|
||||
__asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Store8")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
void
|
||||
|
@ -259,7 +259,7 @@ Store8 (uint8_t *ptr, uint8_t val)
|
|||
}
|
||||
|
||||
void Store64 (uint64_t *ptr, uint64_t val)
|
||||
__asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Store64")
|
||||
__asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Store64")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
void
|
||||
|
@ -271,7 +271,7 @@ Store64 (uint64_t *ptr, uint64_t val)
|
|||
}
|
||||
|
||||
void StoreRel (uint32_t *ptr, uint32_t val)
|
||||
__asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.StoreRel")
|
||||
__asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.StoreRel")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
void
|
||||
|
@ -281,7 +281,7 @@ StoreRel (uint32_t *ptr, uint32_t val)
|
|||
}
|
||||
|
||||
void Storeuintptr (uintptr_t *ptr, uintptr_t val)
|
||||
__asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Storeuintptr")
|
||||
__asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Storeuintptr")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
void
|
||||
|
@ -291,7 +291,7 @@ Storeuintptr (uintptr_t *ptr, uintptr_t val)
|
|||
}
|
||||
|
||||
void StorepNoWB (void *ptr, void *val)
|
||||
__asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.StorepNoWB")
|
||||
__asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.StorepNoWB")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
void
|
||||
|
|
|
@ -1220,12 +1220,12 @@ func newobject(typ *_type) unsafe.Pointer {
|
|||
return mallocgc(typ.size, typ, true)
|
||||
}
|
||||
|
||||
//go:linkname reflect_unsafe_New reflect.unsafe_New
|
||||
//go:linkname reflect_unsafe_New reflect.unsafe__New
|
||||
func reflect_unsafe_New(typ *_type) unsafe.Pointer {
|
||||
return mallocgc(typ.size, typ, true)
|
||||
}
|
||||
|
||||
//go:linkname reflectlite_unsafe_New internal..z2freflectlite.unsafe_New
|
||||
//go:linkname reflectlite_unsafe_New internal_1reflectlite.unsafe__New
|
||||
func reflectlite_unsafe_New(typ *_type) unsafe.Pointer {
|
||||
return mallocgc(typ.size, typ, true)
|
||||
}
|
||||
|
@ -1242,7 +1242,7 @@ func newarray(typ *_type, n int) unsafe.Pointer {
|
|||
return mallocgc(mem, typ, true)
|
||||
}
|
||||
|
||||
//go:linkname reflect_unsafe_NewArray reflect.unsafe_NewArray
|
||||
//go:linkname reflect_unsafe_NewArray reflect.unsafe__NewArray
|
||||
func reflect_unsafe_NewArray(typ *_type, n int) unsafe.Pointer {
|
||||
return newarray(typ, n)
|
||||
}
|
||||
|
|
|
@ -1417,7 +1417,7 @@ func reflect_maplen(h *hmap) int {
|
|||
return h.count
|
||||
}
|
||||
|
||||
//go:linkname reflectlite_maplen internal..z2freflectlite.maplen
|
||||
//go:linkname reflectlite_maplen internal_1reflectlite.maplen
|
||||
func reflectlite_maplen(h *hmap) int {
|
||||
if h == nil {
|
||||
return 0
|
||||
|
|
|
@ -192,7 +192,7 @@ func reflect_typedmemmove(typ *_type, dst, src unsafe.Pointer) {
|
|||
typedmemmove(typ, dst, src)
|
||||
}
|
||||
|
||||
//go:linkname reflectlite_typedmemmove internal..z2freflectlite.typedmemmove
|
||||
//go:linkname reflectlite_typedmemmove internal_1reflectlite.typedmemmove
|
||||
func reflectlite_typedmemmove(typ *_type, dst, src unsafe.Pointer) {
|
||||
reflect_typedmemmove(typ, dst, src)
|
||||
}
|
||||
|
|
|
@ -223,7 +223,7 @@ func gcenable() {
|
|||
memstats.enablegc = true // now that runtime is initialized, GC is okay
|
||||
}
|
||||
|
||||
//go:linkname setGCPercent runtime..z2fdebug.setGCPercent
|
||||
//go:linkname setGCPercent runtime_1debug.setGCPercent
|
||||
func setGCPercent(in int32) (out int32) {
|
||||
// Run on the system stack since we grab the heap lock.
|
||||
systemstack(func() {
|
||||
|
@ -2238,7 +2238,7 @@ func gcResetMarkState() {
|
|||
|
||||
var poolcleanup func()
|
||||
|
||||
//go:linkname sync_runtime_registerPoolCleanup sync.runtime_registerPoolCleanup
|
||||
//go:linkname sync_runtime_registerPoolCleanup sync.runtime__registerPoolCleanup
|
||||
func sync_runtime_registerPoolCleanup(f func()) {
|
||||
poolcleanup = f
|
||||
}
|
||||
|
|
|
@ -1502,7 +1502,7 @@ func (h *mheap) scavengeAll() {
|
|||
}
|
||||
}
|
||||
|
||||
//go:linkname runtime_debug_freeOSMemory runtime..z2fdebug.freeOSMemory
|
||||
//go:linkname runtime_debug_freeOSMemory runtime_1debug.freeOSMemory
|
||||
func runtime_debug_freeOSMemory() {
|
||||
GC()
|
||||
systemstack(func() { mheap_.scavengeAll() })
|
||||
|
|
|
@ -942,7 +942,7 @@ func ThreadCreateProfile(p []StackRecord) (n int, ok bool) {
|
|||
return
|
||||
}
|
||||
|
||||
//go:linkname runtime_goroutineProfileWithLabels runtime..z2fpprof.runtime_goroutineProfileWithLabels
|
||||
//go:linkname runtime_goroutineProfileWithLabels runtime_1pprof.runtime__goroutineProfileWithLabels
|
||||
func runtime_goroutineProfileWithLabels(p []StackRecord, labels []unsafe.Pointer) (n int, ok bool) {
|
||||
return goroutineProfileWithLabels(p, labels)
|
||||
}
|
||||
|
|
|
@ -468,7 +468,7 @@ func readmemstats_m(stats *MemStats) {
|
|||
stats.StackSys += stats.StackInuse
|
||||
}
|
||||
|
||||
//go:linkname readGCStats runtime..z2fdebug.readGCStats
|
||||
//go:linkname readGCStats runtime_1debug.readGCStats
|
||||
func readGCStats(pauses *[]uint64) {
|
||||
systemstack(func() {
|
||||
readGCStats_m(pauses)
|
||||
|
|
|
@ -8,12 +8,12 @@ import (
|
|||
_ "unsafe"
|
||||
)
|
||||
|
||||
//go:linkname runtime_ignoreHangup internal..z2fpoll.runtime_ignoreHangup
|
||||
//go:linkname runtime_ignoreHangup internal_1poll.runtime__ignoreHangup
|
||||
func runtime_ignoreHangup() {
|
||||
getg().m.ignoreHangup = true
|
||||
}
|
||||
|
||||
//go:linkname runtime_unignoreHangup internal..z2fpoll.runtime_unignoreHangup
|
||||
//go:linkname runtime_unignoreHangup internal_1poll.runtime__unignoreHangup
|
||||
func runtime_unignoreHangup(sig string) {
|
||||
getg().m.ignoreHangup = false
|
||||
}
|
||||
|
|
|
@ -113,7 +113,7 @@ var (
|
|||
netpollWaiters uint32
|
||||
)
|
||||
|
||||
//go:linkname poll_runtime_pollServerInit internal..z2fpoll.runtime_pollServerInit
|
||||
//go:linkname poll_runtime_pollServerInit internal_1poll.runtime__pollServerInit
|
||||
func poll_runtime_pollServerInit() {
|
||||
netpollGenericInit()
|
||||
}
|
||||
|
@ -134,7 +134,7 @@ func netpollinited() bool {
|
|||
return atomic.Load(&netpollInited) != 0
|
||||
}
|
||||
|
||||
//go:linkname poll_runtime_isPollServerDescriptor internal..z2fpoll.runtime_isPollServerDescriptor
|
||||
//go:linkname poll_runtime_isPollServerDescriptor internal_1poll.runtime__isPollServerDescriptor
|
||||
|
||||
// poll_runtime_isPollServerDescriptor reports whether fd is a
|
||||
// descriptor being used by netpoll.
|
||||
|
@ -142,7 +142,7 @@ func poll_runtime_isPollServerDescriptor(fd uintptr) bool {
|
|||
return netpollIsPollDescriptor(fd)
|
||||
}
|
||||
|
||||
//go:linkname poll_runtime_pollOpen internal..z2fpoll.runtime_pollOpen
|
||||
//go:linkname poll_runtime_pollOpen internal_1poll.runtime__pollOpen
|
||||
func poll_runtime_pollOpen(fd uintptr) (uintptr, int) {
|
||||
pd := pollcache.alloc()
|
||||
lock(&pd.lock)
|
||||
|
@ -169,7 +169,7 @@ func poll_runtime_pollOpen(fd uintptr) (uintptr, int) {
|
|||
return uintptr(unsafe.Pointer(pd)), int(errno)
|
||||
}
|
||||
|
||||
//go:linkname poll_runtime_pollClose internal..z2fpoll.runtime_pollClose
|
||||
//go:linkname poll_runtime_pollClose internal_1poll.runtime__pollClose
|
||||
func poll_runtime_pollClose(ctx uintptr) {
|
||||
pd := (*pollDesc)(unsafe.Pointer(ctx))
|
||||
if !pd.closing {
|
||||
|
@ -195,7 +195,7 @@ func (c *pollCache) free(pd *pollDesc) {
|
|||
// poll_runtime_pollReset, which is internal/poll.runtime_pollReset,
|
||||
// prepares a descriptor for polling in mode, which is 'r' or 'w'.
|
||||
// This returns an error code; the codes are defined above.
|
||||
//go:linkname poll_runtime_pollReset internal..z2fpoll.runtime_pollReset
|
||||
//go:linkname poll_runtime_pollReset internal_1poll.runtime__pollReset
|
||||
func poll_runtime_pollReset(ctx uintptr, mode int) int {
|
||||
pd := (*pollDesc)(unsafe.Pointer(ctx))
|
||||
errcode := netpollcheckerr(pd, int32(mode))
|
||||
|
@ -214,7 +214,7 @@ func poll_runtime_pollReset(ctx uintptr, mode int) int {
|
|||
// waits for a descriptor to be ready for reading or writing,
|
||||
// according to mode, which is 'r' or 'w'.
|
||||
// This returns an error code; the codes are defined above.
|
||||
//go:linkname poll_runtime_pollWait internal..z2fpoll.runtime_pollWait
|
||||
//go:linkname poll_runtime_pollWait internal_1poll.runtime__pollWait
|
||||
func poll_runtime_pollWait(ctx uintptr, mode int) int {
|
||||
pd := (*pollDesc)(unsafe.Pointer(ctx))
|
||||
errcode := netpollcheckerr(pd, int32(mode))
|
||||
|
@ -237,7 +237,7 @@ func poll_runtime_pollWait(ctx uintptr, mode int) int {
|
|||
return pollNoError
|
||||
}
|
||||
|
||||
//go:linkname poll_runtime_pollWaitCanceled internal..z2fpoll.runtime_pollWaitCanceled
|
||||
//go:linkname poll_runtime_pollWaitCanceled internal_1poll.runtime__pollWaitCanceled
|
||||
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
|
||||
|
@ -246,7 +246,7 @@ func poll_runtime_pollWaitCanceled(ctx uintptr, mode int) {
|
|||
}
|
||||
}
|
||||
|
||||
//go:linkname poll_runtime_pollSetDeadline internal..z2fpoll.runtime_pollSetDeadline
|
||||
//go:linkname poll_runtime_pollSetDeadline internal_1poll.runtime__pollSetDeadline
|
||||
func poll_runtime_pollSetDeadline(ctx uintptr, d int64, mode int) {
|
||||
pd := (*pollDesc)(unsafe.Pointer(ctx))
|
||||
lock(&pd.lock)
|
||||
|
@ -330,7 +330,7 @@ func poll_runtime_pollSetDeadline(ctx uintptr, d int64, mode int) {
|
|||
}
|
||||
}
|
||||
|
||||
//go:linkname poll_runtime_pollUnblock internal..z2fpoll.runtime_pollUnblock
|
||||
//go:linkname poll_runtime_pollUnblock internal_1poll.runtime__pollUnblock
|
||||
func poll_runtime_pollUnblock(ctx uintptr) {
|
||||
pd := (*pollDesc)(unsafe.Pointer(ctx))
|
||||
lock(&pd.lock)
|
||||
|
|
|
@ -91,35 +91,35 @@ func TestMemoryProfiler(t *testing.T) {
|
|||
stk []string
|
||||
legacy string
|
||||
}{{
|
||||
stk: []string{"pprof.allocatePersistent1K", "runtime/pprof.TestMemoryProfiler"},
|
||||
stk: []string{"runtime/pprof.allocatePersistent1K", "runtime/pprof.TestMemoryProfiler"},
|
||||
legacy: fmt.Sprintf(`%v: %v \[%v: %v\] @ 0x[0-9,a-f x]+
|
||||
# 0x[0-9,a-f]+ pprof\.allocatePersistent1K\+0x[0-9,a-f]+ .*/mprof_test\.go:47
|
||||
# 0x[0-9,a-f]+ runtime/pprof\.allocatePersistent1K\+0x[0-9,a-f]+ .*/mprof_test\.go:47
|
||||
# 0x[0-9,a-f]+ runtime/pprof\.TestMemoryProfiler\+0x[0-9,a-f]+ .*/mprof_test\.go:82
|
||||
`, 32*memoryProfilerRun, 1024*memoryProfilerRun, 32*memoryProfilerRun, 1024*memoryProfilerRun),
|
||||
}, {
|
||||
stk: []string{"pprof.allocateTransient1M", "runtime/pprof.TestMemoryProfiler"},
|
||||
stk: []string{"runtime/pprof.allocateTransient1M", "runtime/pprof.TestMemoryProfiler"},
|
||||
legacy: fmt.Sprintf(`(0|%v): (0|%v) \[%v: %v\] @ 0x[0-9,a-f x]+
|
||||
# 0x[0-9,a-f]+ pprof\.allocateTransient1M\+0x[0-9,a-f]+ .*/mprof_test.go:24
|
||||
# 0x[0-9,a-f]+ runtime/pprof\.allocateTransient1M\+0x[0-9,a-f]+ .*/mprof_test.go:24
|
||||
# 0x[0-9,a-f]+ runtime/pprof\.TestMemoryProfiler\+0x[0-9,a-f]+ .*/mprof_test.go:79
|
||||
`, (1<<10)*memoryProfilerRun, (1<<20)*memoryProfilerRun, (1<<10)*memoryProfilerRun, (1<<20)*memoryProfilerRun),
|
||||
}, {
|
||||
stk: []string{"pprof.allocateTransient2M", "runtime/pprof.TestMemoryProfiler"},
|
||||
stk: []string{"runtime/pprof.allocateTransient2M", "runtime/pprof.TestMemoryProfiler"},
|
||||
// This should start with "0: 0" but gccgo's imprecise
|
||||
// GC means that sometimes the value is not collected.
|
||||
legacy: fmt.Sprintf(`(0|%v): (0|%v) \[%v: %v\] @ 0x[0-9,a-f x]+
|
||||
# 0x[0-9,a-f]+ pprof\.allocateTransient2M\+0x[0-9,a-f]+ .*/mprof_test.go:30
|
||||
# 0x[0-9,a-f]+ runtime/pprof\.allocateTransient2M\+0x[0-9,a-f]+ .*/mprof_test.go:30
|
||||
# 0x[0-9,a-f]+ runtime/pprof\.TestMemoryProfiler\+0x[0-9,a-f]+ .*/mprof_test.go:80
|
||||
`, memoryProfilerRun, (2<<20)*memoryProfilerRun, memoryProfilerRun, (2<<20)*memoryProfilerRun),
|
||||
}, {
|
||||
stk: []string{"pprof.allocateTransient2MInline", "runtime/pprof.TestMemoryProfiler"},
|
||||
stk: []string{"runtime/pprof.allocateTransient2MInline", "runtime/pprof.TestMemoryProfiler"},
|
||||
legacy: fmt.Sprintf(`(0|%v): (0|%v) \[%v: %v\] @ 0x[0-9,a-f x]+
|
||||
# 0x[0-9,a-f]+ pprof\.allocateTransient2MInline\+0x[0-9,a-f]+ .*/mprof_test.go:34
|
||||
# 0x[0-9,a-f]+ runtime/pprof\.allocateTransient2MInline\+0x[0-9,a-f]+ .*/mprof_test.go:34
|
||||
# 0x[0-9,a-f]+ runtime/pprof\.TestMemoryProfiler\+0x[0-9,a-f]+ .*/mprof_test.go:81
|
||||
`, memoryProfilerRun, (4<<20)*memoryProfilerRun, memoryProfilerRun, (4<<20)*memoryProfilerRun),
|
||||
}, {
|
||||
stk: []string{"pprof.allocateReflectTransient"},
|
||||
stk: []string{"runtime/pprof.allocateReflectTransient"},
|
||||
legacy: fmt.Sprintf(`(0|%v): (0|%v) \[%v: %v\] @( 0x[0-9,a-f]+)+
|
||||
# 0x[0-9,a-f]+ pprof\.allocateReflectTransient\+0x[0-9,a-f]+ .*/mprof_test.go:55
|
||||
# 0x[0-9,a-f]+ runtime/pprof\.allocateReflectTransient\+0x[0-9,a-f]+ .*/mprof_test.go:55
|
||||
`, memoryProfilerRun, (3<<20)*memoryProfilerRun, memoryProfilerRun, (3<<20)*memoryProfilerRun),
|
||||
}}
|
||||
|
||||
|
|
|
@ -958,8 +958,8 @@ func TestMutexProfile(t *testing.T) {
|
|||
|
||||
stks := stacks(p)
|
||||
for _, want := range [][]string{
|
||||
// {"sync.(*Mutex).Unlock", "pprof.blockMutex.func1"},
|
||||
{"sync.Mutex.Unlock", "pprof.blockMutex..func1"},
|
||||
// {"sync.(*Mutex).Unlock", "runtime/pprof.blockMutex.func1"},
|
||||
{"sync.Mutex.Unlock", "runtime/pprof.blockMutex..func1"},
|
||||
} {
|
||||
if !containsStack(stks, want) {
|
||||
t.Errorf("No matching stack entry for %+v", want)
|
||||
|
|
|
@ -360,7 +360,7 @@ func isAsyncSafePoint(gp *g, pc uintptr) (bool, uintptr) {
|
|||
}
|
||||
name := f.Name()
|
||||
if hasPrefix(name, "runtime.") ||
|
||||
hasPrefix(name, "runtime..z2finternal..z2f") ||
|
||||
hasPrefix(name, "runtime_1internal_1") ||
|
||||
hasPrefix(name, "reflect.") {
|
||||
// For now we never async preempt the runtime or
|
||||
// anything closely tied to the runtime. Known issues
|
||||
|
|
|
@ -263,7 +263,7 @@ func main(unsafe.Pointer) {
|
|||
}
|
||||
|
||||
// os_beforeExit is called from os.Exit(0).
|
||||
//go:linkname os_beforeExit os.runtime_beforeExit
|
||||
//go:linkname os_beforeExit os.runtime__beforeExit
|
||||
func os_beforeExit() {
|
||||
if raceenabled {
|
||||
racefini()
|
||||
|
@ -3305,7 +3305,7 @@ func beforefork() {
|
|||
}
|
||||
|
||||
// Called from syscall package before fork.
|
||||
//go:linkname syscall_runtime_BeforeFork syscall.runtime_BeforeFork
|
||||
//go:linkname syscall_runtime_BeforeFork syscall.runtime__BeforeFork
|
||||
//go:nosplit
|
||||
func syscall_runtime_BeforeFork() {
|
||||
systemstack(beforefork)
|
||||
|
@ -3320,7 +3320,7 @@ func afterfork() {
|
|||
}
|
||||
|
||||
// Called from syscall package after fork in parent.
|
||||
//go:linkname syscall_runtime_AfterFork syscall.runtime_AfterFork
|
||||
//go:linkname syscall_runtime_AfterFork syscall.runtime__AfterFork
|
||||
//go:nosplit
|
||||
func syscall_runtime_AfterFork() {
|
||||
systemstack(afterfork)
|
||||
|
@ -3338,7 +3338,7 @@ var inForkedChild bool
|
|||
// temporarily sharing address space with the parent process, this must
|
||||
// not change any global variables or calling into C code that may do so.
|
||||
//
|
||||
//go:linkname syscall_runtime_AfterForkInChild syscall.runtime_AfterForkInChild
|
||||
//go:linkname syscall_runtime_AfterForkInChild syscall.runtime__AfterForkInChild
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func syscall_runtime_AfterForkInChild() {
|
||||
|
@ -3363,7 +3363,7 @@ func syscall_runtime_AfterForkInChild() {
|
|||
var pendingPreemptSignals uint32
|
||||
|
||||
// Called from syscall package before Exec.
|
||||
//go:linkname syscall_runtime_BeforeExec syscall.runtime_BeforeExec
|
||||
//go:linkname syscall_runtime_BeforeExec syscall.runtime__BeforeExec
|
||||
func syscall_runtime_BeforeExec() {
|
||||
// Prevent thread creation during exec.
|
||||
execLock.lock()
|
||||
|
@ -3378,7 +3378,7 @@ func syscall_runtime_BeforeExec() {
|
|||
}
|
||||
|
||||
// Called from syscall package after Exec.
|
||||
//go:linkname syscall_runtime_AfterExec syscall.runtime_AfterExec
|
||||
//go:linkname syscall_runtime_AfterExec syscall.runtime__AfterExec
|
||||
func syscall_runtime_AfterExec() {
|
||||
execLock.unlock()
|
||||
}
|
||||
|
@ -5165,7 +5165,7 @@ func (l *gList) pop() *g {
|
|||
return gp
|
||||
}
|
||||
|
||||
//go:linkname setMaxThreads runtime..z2fdebug.setMaxThreads
|
||||
//go:linkname setMaxThreads runtime_1debug.setMaxThreads
|
||||
func setMaxThreads(in int) (out int) {
|
||||
lock(&sched.lock)
|
||||
out = int(sched.maxmcount)
|
||||
|
@ -5199,32 +5199,32 @@ func procUnpin() {
|
|||
_g_.m.locks--
|
||||
}
|
||||
|
||||
//go:linkname sync_runtime_procPin sync.runtime_procPin
|
||||
//go:linkname sync_runtime_procPin sync.runtime__procPin
|
||||
//go:nosplit
|
||||
func sync_runtime_procPin() int {
|
||||
return procPin()
|
||||
}
|
||||
|
||||
//go:linkname sync_runtime_procUnpin sync.runtime_procUnpin
|
||||
//go:linkname sync_runtime_procUnpin sync.runtime__procUnpin
|
||||
//go:nosplit
|
||||
func sync_runtime_procUnpin() {
|
||||
procUnpin()
|
||||
}
|
||||
|
||||
//go:linkname sync_atomic_runtime_procPin sync..z2fatomic.runtime_procPin
|
||||
//go:linkname sync_atomic_runtime_procPin sync_1atomic.runtime__procPin
|
||||
//go:nosplit
|
||||
func sync_atomic_runtime_procPin() int {
|
||||
return procPin()
|
||||
}
|
||||
|
||||
//go:linkname sync_atomic_runtime_procUnpin sync..z2fatomic.runtime_procUnpin
|
||||
//go:linkname sync_atomic_runtime_procUnpin sync_1atomic.runtime__procUnpin
|
||||
//go:nosplit
|
||||
func sync_atomic_runtime_procUnpin() {
|
||||
procUnpin()
|
||||
}
|
||||
|
||||
// Active spinning for sync.Mutex.
|
||||
//go:linkname sync_runtime_canSpin sync.runtime_canSpin
|
||||
//go:linkname sync_runtime_canSpin sync.runtime__canSpin
|
||||
//go:nosplit
|
||||
func sync_runtime_canSpin(i int) bool {
|
||||
// sync.Mutex is cooperative, so we are conservative with spinning.
|
||||
|
@ -5241,7 +5241,7 @@ func sync_runtime_canSpin(i int) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
//go:linkname sync_runtime_doSpin sync.runtime_doSpin
|
||||
//go:linkname sync_runtime_doSpin sync.runtime__doSpin
|
||||
//go:nosplit
|
||||
func sync_runtime_doSpin() {
|
||||
procyield(active_spin_cnt)
|
||||
|
|
|
@ -8,7 +8,7 @@ import "unsafe"
|
|||
|
||||
var labelSync uintptr
|
||||
|
||||
//go:linkname runtime_setProfLabel runtime..z2fpprof.runtime_setProfLabel
|
||||
//go:linkname runtime_setProfLabel runtime_1pprof.runtime__setProfLabel
|
||||
func runtime_setProfLabel(labels unsafe.Pointer) {
|
||||
// Introduce race edge for read-back via profile.
|
||||
// This would more properly use &getg().labels as the sync address,
|
||||
|
@ -34,7 +34,7 @@ func runtime_setProfLabel(labels unsafe.Pointer) {
|
|||
getg().labels = labels
|
||||
}
|
||||
|
||||
//go:linkname runtime_getProfLabel runtime..z2fpprof.runtime_getProfLabel
|
||||
//go:linkname runtime_getProfLabel runtime_1pprof.runtime__getProfLabel
|
||||
func runtime_getProfLabel() unsafe.Pointer {
|
||||
return getg().labels
|
||||
}
|
||||
|
|
|
@ -11,14 +11,14 @@ import _ "unsafe" // for go:linkname
|
|||
// maxstacksize.
|
||||
var maxstacksize uintptr = 1 << 20 // enough until runtime.main sets it for real
|
||||
|
||||
//go:linkname setMaxStack runtime..z2fdebug.setMaxStack
|
||||
//go:linkname setMaxStack runtime_1debug.setMaxStack
|
||||
func setMaxStack(in int) (out int) {
|
||||
out = int(maxstacksize)
|
||||
maxstacksize = uintptr(in)
|
||||
return out
|
||||
}
|
||||
|
||||
//go:linkname setPanicOnFault runtime..z2fdebug.setPanicOnFault
|
||||
//go:linkname setPanicOnFault runtime_1debug.setPanicOnFault
|
||||
func setPanicOnFault(new bool) (old bool) {
|
||||
_g_ := getg()
|
||||
old = _g_.paniconfault
|
||||
|
|
|
@ -51,13 +51,13 @@ func tickspersecond() int64 {
|
|||
var envs []string
|
||||
var argslice []string
|
||||
|
||||
//go:linkname syscall_runtime_envs syscall.runtime_envs
|
||||
//go:linkname syscall_runtime_envs syscall.runtime__envs
|
||||
func syscall_runtime_envs() []string { return append([]string{}, envs...) }
|
||||
|
||||
//go:linkname syscall_Getpagesize syscall.Getpagesize
|
||||
func syscall_Getpagesize() int { return int(physPageSize) }
|
||||
|
||||
//go:linkname os_runtime_args os.runtime_args
|
||||
//go:linkname os_runtime_args os.runtime__args
|
||||
func os_runtime_args() []string { return append([]string{}, argslice...) }
|
||||
|
||||
//go:linkname syscall_Exit syscall.Exit
|
||||
|
|
|
@ -398,7 +398,7 @@ func parsedebugvars() {
|
|||
traceback_env = traceback_cache
|
||||
}
|
||||
|
||||
//go:linkname setTraceback runtime..z2fdebug.SetTraceback
|
||||
//go:linkname setTraceback runtime_1debug.SetTraceback
|
||||
func setTraceback(level string) {
|
||||
var t uint32
|
||||
switch level {
|
||||
|
|
|
@ -51,27 +51,27 @@ var semtable [semTabSize]struct {
|
|||
pad [cpu.CacheLinePadSize - unsafe.Sizeof(semaRoot{})]byte
|
||||
}
|
||||
|
||||
//go:linkname sync_runtime_Semacquire sync.runtime_Semacquire
|
||||
//go:linkname sync_runtime_Semacquire sync.runtime__Semacquire
|
||||
func sync_runtime_Semacquire(addr *uint32) {
|
||||
semacquire1(addr, false, semaBlockProfile, 0)
|
||||
}
|
||||
|
||||
//go:linkname poll_runtime_Semacquire internal..z2fpoll.runtime_Semacquire
|
||||
//go:linkname poll_runtime_Semacquire internal_1poll.runtime__Semacquire
|
||||
func poll_runtime_Semacquire(addr *uint32) {
|
||||
semacquire1(addr, false, semaBlockProfile, 0)
|
||||
}
|
||||
|
||||
//go:linkname sync_runtime_Semrelease sync.runtime_Semrelease
|
||||
//go:linkname sync_runtime_Semrelease sync.runtime__Semrelease
|
||||
func sync_runtime_Semrelease(addr *uint32, handoff bool, skipframes int) {
|
||||
semrelease1(addr, handoff, skipframes)
|
||||
}
|
||||
|
||||
//go:linkname sync_runtime_SemacquireMutex sync.runtime_SemacquireMutex
|
||||
//go:linkname sync_runtime_SemacquireMutex sync.runtime__SemacquireMutex
|
||||
func sync_runtime_SemacquireMutex(addr *uint32, lifo bool, skipframes int) {
|
||||
semacquire1(addr, lifo, semaBlockProfile|semaMutexProfile, skipframes)
|
||||
}
|
||||
|
||||
//go:linkname poll_runtime_Semrelease internal..z2fpoll.runtime_Semrelease
|
||||
//go:linkname poll_runtime_Semrelease internal_1poll.runtime__Semrelease
|
||||
func poll_runtime_Semrelease(addr *uint32) {
|
||||
semrelease(addr)
|
||||
}
|
||||
|
@ -475,7 +475,7 @@ func less(a, b uint32) bool {
|
|||
// notifyListAdd adds the caller to a notify list such that it can receive
|
||||
// notifications. The caller must eventually call notifyListWait to wait for
|
||||
// such a notification, passing the returned ticket number.
|
||||
//go:linkname notifyListAdd sync.runtime_notifyListAdd
|
||||
//go:linkname notifyListAdd sync.runtime__notifyListAdd
|
||||
func notifyListAdd(l *notifyList) uint32 {
|
||||
// This may be called concurrently, for example, when called from
|
||||
// sync.Cond.Wait while holding a RWMutex in read mode.
|
||||
|
@ -484,7 +484,7 @@ func notifyListAdd(l *notifyList) uint32 {
|
|||
|
||||
// notifyListWait waits for a notification. If one has been sent since
|
||||
// notifyListAdd was called, it returns immediately. Otherwise, it blocks.
|
||||
//go:linkname notifyListWait sync.runtime_notifyListWait
|
||||
//go:linkname notifyListWait sync.runtime__notifyListWait
|
||||
func notifyListWait(l *notifyList, t uint32) {
|
||||
lockWithRank(&l.lock, lockRankNotifyList)
|
||||
|
||||
|
@ -518,7 +518,7 @@ func notifyListWait(l *notifyList, t uint32) {
|
|||
}
|
||||
|
||||
// notifyListNotifyAll notifies all entries in the list.
|
||||
//go:linkname notifyListNotifyAll sync.runtime_notifyListNotifyAll
|
||||
//go:linkname notifyListNotifyAll sync.runtime__notifyListNotifyAll
|
||||
func notifyListNotifyAll(l *notifyList) {
|
||||
// Fast-path: if there are no new waiters since the last notification
|
||||
// we don't need to acquire the lock.
|
||||
|
@ -550,7 +550,7 @@ func notifyListNotifyAll(l *notifyList) {
|
|||
}
|
||||
|
||||
// notifyListNotifyOne notifies one entry in the list.
|
||||
//go:linkname notifyListNotifyOne sync.runtime_notifyListNotifyOne
|
||||
//go:linkname notifyListNotifyOne sync.runtime__notifyListNotifyOne
|
||||
func notifyListNotifyOne(l *notifyList) {
|
||||
// Fast-path: if there are no new waiters since the last notification
|
||||
// we don't need to acquire the lock at all.
|
||||
|
@ -603,7 +603,7 @@ func notifyListNotifyOne(l *notifyList) {
|
|||
unlock(&l.lock)
|
||||
}
|
||||
|
||||
//go:linkname notifyListCheck sync.runtime_notifyListCheck
|
||||
//go:linkname notifyListCheck sync.runtime__notifyListCheck
|
||||
func notifyListCheck(sz uintptr) {
|
||||
if sz != unsafe.Sizeof(notifyList{}) {
|
||||
print("runtime: bad notifyList size - sync=", sz, " runtime=", unsafe.Sizeof(notifyList{}), "\n")
|
||||
|
@ -611,7 +611,7 @@ func notifyListCheck(sz uintptr) {
|
|||
}
|
||||
}
|
||||
|
||||
//go:linkname sync_nanotime sync.runtime_nanotime
|
||||
//go:linkname sync_nanotime sync.runtime__nanotime
|
||||
func sync_nanotime() int64 {
|
||||
return nanotime()
|
||||
}
|
||||
|
|
|
@ -121,7 +121,7 @@ Send:
|
|||
|
||||
// Called to receive the next queued signal.
|
||||
// Must only be called from a single goroutine at a time.
|
||||
//go:linkname signal_recv os..z2fsignal.signal_recv
|
||||
//go:linkname signal_recv os_1signal.signal__recv
|
||||
func signal_recv() uint32 {
|
||||
for {
|
||||
// Serve any signals from local copy.
|
||||
|
@ -169,7 +169,7 @@ func signal_recv() uint32 {
|
|||
// the signal(s) in question, and here we are just waiting to make sure
|
||||
// that all the signals have been delivered to the user channels
|
||||
// by the os/signal package.
|
||||
//go:linkname signalWaitUntilIdle os..z2fsignal.signalWaitUntilIdle
|
||||
//go:linkname signalWaitUntilIdle os_1signal.signalWaitUntilIdle
|
||||
func signalWaitUntilIdle() {
|
||||
// Although the signals we care about have been removed from
|
||||
// sig.wanted, it is possible that another thread has received
|
||||
|
@ -189,7 +189,7 @@ func signalWaitUntilIdle() {
|
|||
}
|
||||
|
||||
// Must only be called from a single goroutine at a time.
|
||||
//go:linkname signal_enable os..z2fsignal.signal_enable
|
||||
//go:linkname signal_enable os_1signal.signal__enable
|
||||
func signal_enable(s uint32) {
|
||||
if !sig.inuse {
|
||||
// This is the first call to signal_enable. Initialize.
|
||||
|
@ -217,7 +217,7 @@ func signal_enable(s uint32) {
|
|||
}
|
||||
|
||||
// Must only be called from a single goroutine at a time.
|
||||
//go:linkname signal_disable os..z2fsignal.signal_disable
|
||||
//go:linkname signal_disable os_1signal.signal__disable
|
||||
func signal_disable(s uint32) {
|
||||
if s >= uint32(len(sig.wanted)*32) {
|
||||
return
|
||||
|
@ -230,7 +230,7 @@ func signal_disable(s uint32) {
|
|||
}
|
||||
|
||||
// Must only be called from a single goroutine at a time.
|
||||
//go:linkname signal_ignore os..z2fsignal.signal_ignore
|
||||
//go:linkname signal_ignore os_1signal.signal__ignore
|
||||
func signal_ignore(s uint32) {
|
||||
if s >= uint32(len(sig.wanted)*32) {
|
||||
return
|
||||
|
@ -257,7 +257,7 @@ func sigInitIgnored(s uint32) {
|
|||
}
|
||||
|
||||
// Checked by signal handlers.
|
||||
//go:linkname signal_ignored os..z2fsignal.signal_ignored
|
||||
//go:linkname signal_ignored os_1signal.signal__ignored
|
||||
func signal_ignored(s uint32) bool {
|
||||
i := atomic.Load(&sig.ignored[s/32])
|
||||
return i&(1<<(s&31)) != 0
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
package runtime
|
||||
|
||||
import (
|
||||
"internal/bytealg"
|
||||
_ "unsafe" // for go:linkname
|
||||
)
|
||||
|
||||
|
@ -119,7 +120,7 @@ func pcInlineCallers(pc uintptr, locbuf *location, max int32) int32
|
|||
// runtime_expandFinalInlineFrame expands the final pc in stk to include all
|
||||
// "callers" if pc is inline.
|
||||
//
|
||||
//go:linkname runtime_expandFinalInlineFrame runtime..z2fpprof.runtime_expandFinalInlineFrame
|
||||
//go:linkname runtime_expandFinalInlineFrame runtime_1pprof.runtime__expandFinalInlineFrame
|
||||
func runtime_expandFinalInlineFrame(stk []uintptr) []uintptr {
|
||||
if len(stk) == 0 {
|
||||
return stk
|
||||
|
@ -210,42 +211,62 @@ func hexDigitsToRune(digits []byte, ndig int) rune {
|
|||
return rune(result)
|
||||
}
|
||||
|
||||
// Perform an in-place decoding on the input byte slice. This looks
|
||||
// for "..z<hex 2 >", "..u<hex x 4>" and "..U<hex x 8>" and overwrites
|
||||
// with the encoded bytes corresponding to the unicode in question.
|
||||
// Return value is the number of bytes taken by the result.
|
||||
|
||||
// decodeIdentifier performs an in-place decoding on the input byte slice.
|
||||
// This undoes the compiler underscore mangling.
|
||||
// Returns the number of bytes used by the result.
|
||||
func decodeIdentifier(bsl []byte) int {
|
||||
underscoreCodes := map[byte]byte{
|
||||
'_': '_',
|
||||
'0': '.',
|
||||
'1': '/',
|
||||
'2': '*',
|
||||
'3': ',',
|
||||
'4': '{',
|
||||
'5': '}',
|
||||
'6': '[',
|
||||
'7': ']',
|
||||
'8': '(',
|
||||
'9': ')',
|
||||
'a': '"',
|
||||
'b': ' ',
|
||||
'c': ';',
|
||||
}
|
||||
|
||||
j := 0
|
||||
for i := 0; i < len(bsl); i++ {
|
||||
b := bsl[i]
|
||||
|
||||
if i+1 < len(bsl) && bsl[i] == '.' && bsl[i+1] == '.' {
|
||||
if i+4 < len(bsl) && bsl[i+2] == 'z' {
|
||||
digits := bsl[i+3:]
|
||||
r := hexDigitsToRune(digits, 2)
|
||||
nc := encoderune(bsl[j:], r)
|
||||
j += nc
|
||||
i += 4
|
||||
continue
|
||||
} else if i+6 < len(bsl) && bsl[i+2] == 'u' {
|
||||
digits := bsl[i+3:]
|
||||
r := hexDigitsToRune(digits, 4)
|
||||
nc := encoderune(bsl[j:], r)
|
||||
j += nc
|
||||
i += 6
|
||||
continue
|
||||
} else if i+10 < len(bsl) && bsl[i+2] == 'U' {
|
||||
digits := bsl[i+3:]
|
||||
r := hexDigitsToRune(digits, 8)
|
||||
nc := encoderune(bsl[j:], r)
|
||||
j += nc
|
||||
i += 10
|
||||
continue
|
||||
}
|
||||
if b != '_' || i+1 >= len(bsl) {
|
||||
bsl[j] = b
|
||||
j++
|
||||
continue
|
||||
}
|
||||
|
||||
if d, ok := underscoreCodes[bsl[i+1]]; ok {
|
||||
i++
|
||||
bsl[j] = d
|
||||
j++
|
||||
continue
|
||||
}
|
||||
|
||||
rlen := 0
|
||||
switch bsl[i+1] {
|
||||
case 'x':
|
||||
rlen = 2
|
||||
case 'u':
|
||||
rlen = 4
|
||||
case 'U':
|
||||
rlen = 8
|
||||
}
|
||||
|
||||
if rlen > 0 && i+1+rlen < len(bsl) {
|
||||
r := hexDigitsToRune(bsl[i+2:], rlen)
|
||||
nc := encoderune(bsl[j:], r)
|
||||
j += nc
|
||||
i += rlen + 1
|
||||
} else {
|
||||
bsl[j] = b
|
||||
j++
|
||||
}
|
||||
bsl[j] = b
|
||||
j += 1
|
||||
}
|
||||
return j
|
||||
}
|
||||
|
@ -254,6 +275,11 @@ func decodeIdentifier(bsl []byte) int {
|
|||
// as used in the compiler.
|
||||
|
||||
func demangleSymbol(s string) string {
|
||||
if bytealg.IndexByteString(s, '.') < 0 {
|
||||
// A symbol with no '.' is not a Go symbol.
|
||||
return s
|
||||
}
|
||||
|
||||
bsl := []byte(s)
|
||||
nchars := decodeIdentifier(bsl)
|
||||
bsl = bsl[:nchars]
|
||||
|
|
|
@ -1152,7 +1152,7 @@ func traceNextGC() {
|
|||
// To access runtime functions from runtime/trace.
|
||||
// See runtime/trace/annotation.go
|
||||
|
||||
//go:linkname trace_userTaskCreate runtime..z2ftrace.userTaskCreate
|
||||
//go:linkname trace_userTaskCreate runtime_1trace.userTaskCreate
|
||||
func trace_userTaskCreate(id, parentID uint64, taskType string) {
|
||||
if !trace.enabled {
|
||||
return
|
||||
|
@ -1170,12 +1170,12 @@ func trace_userTaskCreate(id, parentID uint64, taskType string) {
|
|||
traceReleaseBuffer(pid)
|
||||
}
|
||||
|
||||
//go:linkname trace_userTaskEnd runtime..z2ftrace.userTaskEnd
|
||||
//go:linkname trace_userTaskEnd runtime_1trace.userTaskEnd
|
||||
func trace_userTaskEnd(id uint64) {
|
||||
traceEvent(traceEvUserTaskEnd, 2, id)
|
||||
}
|
||||
|
||||
//go:linkname trace_userRegion runtime..z2ftrace.userRegion
|
||||
//go:linkname trace_userRegion runtime_1trace.userRegion
|
||||
func trace_userRegion(id, mode uint64, name string) {
|
||||
if !trace.enabled {
|
||||
return
|
||||
|
@ -1192,7 +1192,7 @@ func trace_userRegion(id, mode uint64, name string) {
|
|||
traceReleaseBuffer(pid)
|
||||
}
|
||||
|
||||
//go:linkname trace_userLog runtime..z2ftrace.userLog
|
||||
//go:linkname trace_userLog runtime_1trace.userLog
|
||||
func trace_userLog(id uint64, category, message string) {
|
||||
if !trace.enabled {
|
||||
return
|
||||
|
|
|
@ -184,10 +184,10 @@ func showfuncinfo(name string, firstFrame bool) bool {
|
|||
// isExportedRuntime reports whether name is an exported runtime function.
|
||||
// It is only for runtime functions, so ASCII A-Z is fine. Here also check
|
||||
// for mangled functions from runtime/<...>, which will be prefixed with
|
||||
// "runtime..z2f".
|
||||
// "runtime_1".
|
||||
func isExportedRuntime(name string) bool {
|
||||
const n = len("runtime.")
|
||||
if hasPrefix(name, "runtime..z2f") {
|
||||
if hasPrefix(name, "runtime_1") {
|
||||
return true
|
||||
}
|
||||
return len(name) > n && name[:n] == "runtime." && 'A' <= name[n] && name[n] <= 'Z'
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include "runtime.h"
|
||||
|
||||
int32_t SwapInt32 (int32_t *, int32_t)
|
||||
__asm__ (GOSYM_PREFIX "sync..z2fatomic.SwapInt32")
|
||||
__asm__ (GOSYM_PREFIX "sync_1atomic.SwapInt32")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
int32_t
|
||||
|
@ -19,7 +19,7 @@ SwapInt32 (int32_t *addr, int32_t new)
|
|||
}
|
||||
|
||||
int64_t SwapInt64 (int64_t *, int64_t)
|
||||
__asm__ (GOSYM_PREFIX "sync..z2fatomic.SwapInt64")
|
||||
__asm__ (GOSYM_PREFIX "sync_1atomic.SwapInt64")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
int64_t
|
||||
|
@ -31,7 +31,7 @@ SwapInt64 (int64_t *addr, int64_t new)
|
|||
}
|
||||
|
||||
uint32_t SwapUint32 (uint32_t *, uint32_t)
|
||||
__asm__ (GOSYM_PREFIX "sync..z2fatomic.SwapUint32")
|
||||
__asm__ (GOSYM_PREFIX "sync_1atomic.SwapUint32")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
uint32_t
|
||||
|
@ -41,7 +41,7 @@ SwapUint32 (uint32_t *addr, uint32_t new)
|
|||
}
|
||||
|
||||
uint64_t SwapUint64 (uint64_t *, uint64_t)
|
||||
__asm__ (GOSYM_PREFIX "sync..z2fatomic.SwapUint64")
|
||||
__asm__ (GOSYM_PREFIX "sync_1atomic.SwapUint64")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
uint64_t
|
||||
|
@ -53,7 +53,7 @@ SwapUint64 (uint64_t *addr, uint64_t new)
|
|||
}
|
||||
|
||||
uintptr_t SwapUintptr (uintptr_t *, uintptr_t)
|
||||
__asm__ (GOSYM_PREFIX "sync..z2fatomic.SwapUintptr")
|
||||
__asm__ (GOSYM_PREFIX "sync_1atomic.SwapUintptr")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
uintptr_t
|
||||
|
@ -63,7 +63,7 @@ SwapUintptr (uintptr_t *addr, uintptr_t new)
|
|||
}
|
||||
|
||||
_Bool CompareAndSwapInt32 (int32_t *, int32_t, int32_t)
|
||||
__asm__ (GOSYM_PREFIX "sync..z2fatomic.CompareAndSwapInt32")
|
||||
__asm__ (GOSYM_PREFIX "sync_1atomic.CompareAndSwapInt32")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
_Bool
|
||||
|
@ -74,7 +74,7 @@ CompareAndSwapInt32 (int32_t *val, int32_t old, int32_t new)
|
|||
}
|
||||
|
||||
_Bool CompareAndSwapInt64 (int64_t *, int64_t, int64_t)
|
||||
__asm__ (GOSYM_PREFIX "sync..z2fatomic.CompareAndSwapInt64")
|
||||
__asm__ (GOSYM_PREFIX "sync_1atomic.CompareAndSwapInt64")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
_Bool
|
||||
|
@ -87,7 +87,7 @@ CompareAndSwapInt64 (int64_t *val, int64_t old, int64_t new)
|
|||
}
|
||||
|
||||
_Bool CompareAndSwapUint32 (uint32_t *, uint32_t, uint32_t)
|
||||
__asm__ (GOSYM_PREFIX "sync..z2fatomic.CompareAndSwapUint32")
|
||||
__asm__ (GOSYM_PREFIX "sync_1atomic.CompareAndSwapUint32")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
_Bool
|
||||
|
@ -98,7 +98,7 @@ CompareAndSwapUint32 (uint32_t *val, uint32_t old, uint32_t new)
|
|||
}
|
||||
|
||||
_Bool CompareAndSwapUint64 (uint64_t *, uint64_t, uint64_t)
|
||||
__asm__ (GOSYM_PREFIX "sync..z2fatomic.CompareAndSwapUint64")
|
||||
__asm__ (GOSYM_PREFIX "sync_1atomic.CompareAndSwapUint64")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
_Bool
|
||||
|
@ -111,7 +111,7 @@ CompareAndSwapUint64 (uint64_t *val, uint64_t old, uint64_t new)
|
|||
}
|
||||
|
||||
_Bool CompareAndSwapUintptr (uintptr_t *, uintptr_t, uintptr_t)
|
||||
__asm__ (GOSYM_PREFIX "sync..z2fatomic.CompareAndSwapUintptr")
|
||||
__asm__ (GOSYM_PREFIX "sync_1atomic.CompareAndSwapUintptr")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
_Bool
|
||||
|
@ -122,7 +122,7 @@ CompareAndSwapUintptr (uintptr_t *val, uintptr_t old, uintptr_t new)
|
|||
}
|
||||
|
||||
int32_t AddInt32 (int32_t *, int32_t)
|
||||
__asm__ (GOSYM_PREFIX "sync..z2fatomic.AddInt32")
|
||||
__asm__ (GOSYM_PREFIX "sync_1atomic.AddInt32")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
int32_t
|
||||
|
@ -132,7 +132,7 @@ AddInt32 (int32_t *val, int32_t delta)
|
|||
}
|
||||
|
||||
uint32_t AddUint32 (uint32_t *, uint32_t)
|
||||
__asm__ (GOSYM_PREFIX "sync..z2fatomic.AddUint32")
|
||||
__asm__ (GOSYM_PREFIX "sync_1atomic.AddUint32")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
uint32_t
|
||||
|
@ -142,7 +142,7 @@ AddUint32 (uint32_t *val, uint32_t delta)
|
|||
}
|
||||
|
||||
int64_t AddInt64 (int64_t *, int64_t)
|
||||
__asm__ (GOSYM_PREFIX "sync..z2fatomic.AddInt64")
|
||||
__asm__ (GOSYM_PREFIX "sync_1atomic.AddInt64")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
int64_t
|
||||
|
@ -154,7 +154,7 @@ AddInt64 (int64_t *val, int64_t delta)
|
|||
}
|
||||
|
||||
uint64_t AddUint64 (uint64_t *, uint64_t)
|
||||
__asm__ (GOSYM_PREFIX "sync..z2fatomic.AddUint64")
|
||||
__asm__ (GOSYM_PREFIX "sync_1atomic.AddUint64")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
uint64_t
|
||||
|
@ -166,7 +166,7 @@ AddUint64 (uint64_t *val, uint64_t delta)
|
|||
}
|
||||
|
||||
uintptr_t AddUintptr (uintptr_t *, uintptr_t)
|
||||
__asm__ (GOSYM_PREFIX "sync..z2fatomic.AddUintptr")
|
||||
__asm__ (GOSYM_PREFIX "sync_1atomic.AddUintptr")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
uintptr_t
|
||||
|
@ -176,7 +176,7 @@ AddUintptr (uintptr_t *val, uintptr_t delta)
|
|||
}
|
||||
|
||||
int32_t LoadInt32 (int32_t *addr)
|
||||
__asm__ (GOSYM_PREFIX "sync..z2fatomic.LoadInt32")
|
||||
__asm__ (GOSYM_PREFIX "sync_1atomic.LoadInt32")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
int32_t
|
||||
|
@ -186,7 +186,7 @@ LoadInt32 (int32_t *addr)
|
|||
}
|
||||
|
||||
int64_t LoadInt64 (int64_t *addr)
|
||||
__asm__ (GOSYM_PREFIX "sync..z2fatomic.LoadInt64")
|
||||
__asm__ (GOSYM_PREFIX "sync_1atomic.LoadInt64")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
int64_t
|
||||
|
@ -198,7 +198,7 @@ LoadInt64 (int64_t *addr)
|
|||
}
|
||||
|
||||
uint32_t LoadUint32 (uint32_t *addr)
|
||||
__asm__ (GOSYM_PREFIX "sync..z2fatomic.LoadUint32")
|
||||
__asm__ (GOSYM_PREFIX "sync_1atomic.LoadUint32")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
uint32_t
|
||||
|
@ -208,7 +208,7 @@ LoadUint32 (uint32_t *addr)
|
|||
}
|
||||
|
||||
uint64_t LoadUint64 (uint64_t *addr)
|
||||
__asm__ (GOSYM_PREFIX "sync..z2fatomic.LoadUint64")
|
||||
__asm__ (GOSYM_PREFIX "sync_1atomic.LoadUint64")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
uint64_t
|
||||
|
@ -220,7 +220,7 @@ LoadUint64 (uint64_t *addr)
|
|||
}
|
||||
|
||||
uintptr_t LoadUintptr (uintptr_t *addr)
|
||||
__asm__ (GOSYM_PREFIX "sync..z2fatomic.LoadUintptr")
|
||||
__asm__ (GOSYM_PREFIX "sync_1atomic.LoadUintptr")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
uintptr_t
|
||||
|
@ -230,7 +230,7 @@ LoadUintptr (uintptr_t *addr)
|
|||
}
|
||||
|
||||
void *LoadPointer (void **addr)
|
||||
__asm__ (GOSYM_PREFIX "sync..z2fatomic.LoadPointer")
|
||||
__asm__ (GOSYM_PREFIX "sync_1atomic.LoadPointer")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
void *
|
||||
|
@ -240,7 +240,7 @@ LoadPointer (void **addr)
|
|||
}
|
||||
|
||||
void StoreInt32 (int32_t *addr, int32_t val)
|
||||
__asm__ (GOSYM_PREFIX "sync..z2fatomic.StoreInt32")
|
||||
__asm__ (GOSYM_PREFIX "sync_1atomic.StoreInt32")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
void
|
||||
|
@ -250,7 +250,7 @@ StoreInt32 (int32_t *addr, int32_t val)
|
|||
}
|
||||
|
||||
void StoreInt64 (int64_t *addr, int64_t val)
|
||||
__asm__ (GOSYM_PREFIX "sync..z2fatomic.StoreInt64")
|
||||
__asm__ (GOSYM_PREFIX "sync_1atomic.StoreInt64")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
void
|
||||
|
@ -262,7 +262,7 @@ StoreInt64 (int64_t *addr, int64_t val)
|
|||
}
|
||||
|
||||
void StoreUint32 (uint32_t *addr, uint32_t val)
|
||||
__asm__ (GOSYM_PREFIX "sync..z2fatomic.StoreUint32")
|
||||
__asm__ (GOSYM_PREFIX "sync_1atomic.StoreUint32")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
void
|
||||
|
@ -272,7 +272,7 @@ StoreUint32 (uint32_t *addr, uint32_t val)
|
|||
}
|
||||
|
||||
void StoreUint64 (uint64_t *addr, uint64_t val)
|
||||
__asm__ (GOSYM_PREFIX "sync..z2fatomic.StoreUint64")
|
||||
__asm__ (GOSYM_PREFIX "sync_1atomic.StoreUint64")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
void
|
||||
|
@ -284,7 +284,7 @@ StoreUint64 (uint64_t *addr, uint64_t val)
|
|||
}
|
||||
|
||||
void StoreUintptr (uintptr_t *addr, uintptr_t val)
|
||||
__asm__ (GOSYM_PREFIX "sync..z2fatomic.StoreUintptr")
|
||||
__asm__ (GOSYM_PREFIX "sync_1atomic.StoreUintptr")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
void
|
||||
|
|
|
@ -16,36 +16,36 @@
|
|||
the libffi type values. */
|
||||
|
||||
ffi_type *go_ffi_type_pointer(void) __attribute__ ((no_split_stack));
|
||||
ffi_type *go_ffi_type_pointer(void) __asm__ ("runtime.ffi_type_pointer");
|
||||
ffi_type *go_ffi_type_pointer(void) __asm__ ("runtime.ffi__type__pointer");
|
||||
ffi_type *go_ffi_type_sint8(void) __attribute__ ((no_split_stack));
|
||||
ffi_type *go_ffi_type_sint8(void) __asm__ ("runtime.ffi_type_sint8");
|
||||
ffi_type *go_ffi_type_sint8(void) __asm__ ("runtime.ffi__type__sint8");
|
||||
ffi_type *go_ffi_type_sint16(void) __attribute__ ((no_split_stack));
|
||||
ffi_type *go_ffi_type_sint16(void) __asm__ ("runtime.ffi_type_sint16");
|
||||
ffi_type *go_ffi_type_sint16(void) __asm__ ("runtime.ffi__type__sint16");
|
||||
ffi_type *go_ffi_type_sint32(void) __attribute__ ((no_split_stack));
|
||||
ffi_type *go_ffi_type_sint32(void) __asm__ ("runtime.ffi_type_sint32");
|
||||
ffi_type *go_ffi_type_sint32(void) __asm__ ("runtime.ffi__type__sint32");
|
||||
ffi_type *go_ffi_type_sint64(void) __attribute__ ((no_split_stack));
|
||||
ffi_type *go_ffi_type_sint64(void) __asm__ ("runtime.ffi_type_sint64");
|
||||
ffi_type *go_ffi_type_sint64(void) __asm__ ("runtime.ffi__type__sint64");
|
||||
ffi_type *go_ffi_type_uint8(void) __attribute__ ((no_split_stack));
|
||||
ffi_type *go_ffi_type_uint8(void) __asm__ ("runtime.ffi_type_uint8");
|
||||
ffi_type *go_ffi_type_uint8(void) __asm__ ("runtime.ffi__type__uint8");
|
||||
ffi_type *go_ffi_type_uint16(void) __attribute__ ((no_split_stack));
|
||||
ffi_type *go_ffi_type_uint16(void) __asm__ ("runtime.ffi_type_uint16");
|
||||
ffi_type *go_ffi_type_uint16(void) __asm__ ("runtime.ffi__type__uint16");
|
||||
ffi_type *go_ffi_type_uint32(void) __attribute__ ((no_split_stack));
|
||||
ffi_type *go_ffi_type_uint32(void) __asm__ ("runtime.ffi_type_uint32");
|
||||
ffi_type *go_ffi_type_uint32(void) __asm__ ("runtime.ffi__type__uint32");
|
||||
ffi_type *go_ffi_type_uint64(void) __attribute__ ((no_split_stack));
|
||||
ffi_type *go_ffi_type_uint64(void) __asm__ ("runtime.ffi_type_uint64");
|
||||
ffi_type *go_ffi_type_uint64(void) __asm__ ("runtime.ffi__type__uint64");
|
||||
ffi_type *go_ffi_type_float(void) __attribute__ ((no_split_stack));
|
||||
ffi_type *go_ffi_type_float(void) __asm__ ("runtime.ffi_type_float");
|
||||
ffi_type *go_ffi_type_float(void) __asm__ ("runtime.ffi__type__float");
|
||||
ffi_type *go_ffi_type_double(void) __attribute__ ((no_split_stack));
|
||||
ffi_type *go_ffi_type_double(void) __asm__ ("runtime.ffi_type_double");
|
||||
ffi_type *go_ffi_type_double(void) __asm__ ("runtime.ffi__type__double");
|
||||
ffi_type *go_ffi_type_complex_float(void) __attribute__ ((no_split_stack));
|
||||
ffi_type *go_ffi_type_complex_float(void) __asm__ ("runtime.ffi_type_complex_float");
|
||||
ffi_type *go_ffi_type_complex_float(void) __asm__ ("runtime.ffi__type__complex__float");
|
||||
ffi_type *go_ffi_type_complex_double(void) __attribute__ ((no_split_stack));
|
||||
ffi_type *go_ffi_type_complex_double(void) __asm__ ("runtime.ffi_type_complex_double");
|
||||
ffi_type *go_ffi_type_complex_double(void) __asm__ ("runtime.ffi__type__complex__double");
|
||||
ffi_type *go_ffi_type_void(void) __attribute__ ((no_split_stack));
|
||||
ffi_type *go_ffi_type_void(void) __asm__ ("runtime.ffi_type_void");
|
||||
ffi_type *go_ffi_type_void(void) __asm__ ("runtime.ffi__type__void");
|
||||
|
||||
_Bool go_ffi_supports_complex(void) __attribute__ ((no_split_stack));
|
||||
_Bool go_ffi_supports_complex(void) __asm__ ("runtime.ffi_supports_complex");
|
||||
_Bool go_ffi_supports_complex(void) __asm__ ("runtime.ffi__supports__complex");
|
||||
|
||||
ffi_type *
|
||||
go_ffi_type_pointer(void)
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
/* Set the C environment from Go. This is called by syscall.Setenv. */
|
||||
|
||||
void setenv_c (String, String) __asm__ (GOSYM_PREFIX "syscall.setenv_c");
|
||||
void setenv_c (String, String) __asm__ (GOSYM_PREFIX "syscall.setenv__c");
|
||||
|
||||
void
|
||||
setenv_c (String k, String v)
|
||||
|
|
|
@ -72,7 +72,7 @@ const struct _type unsafe_Pointer =
|
|||
it to be defined elsewhere. */
|
||||
|
||||
extern const struct ptrtype pointer_unsafe_Pointer
|
||||
__asm__ (GOSYM_PREFIX "type...1unsafe.Pointer");
|
||||
__asm__ (GOSYM_PREFIX "unsafe.Pointer..p");
|
||||
|
||||
/* The reflection string. */
|
||||
#define PREFLECTION "*unsafe.Pointer"
|
||||
|
@ -83,7 +83,7 @@ static const String preflection_string =
|
|||
};
|
||||
|
||||
extern const byte pointer_unsafe_Pointer_gc[]
|
||||
__asm__ (GOSYM_PREFIX "type...1unsafe.Pointer..g");
|
||||
__asm__ (GOSYM_PREFIX "unsafe.Pointer..p..g");
|
||||
|
||||
const byte pointer_unsafe_Pointer_gc[] = { 1 };
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
/* Unset an environment variable from Go. This is called by
|
||||
syscall.Unsetenv. */
|
||||
|
||||
void unsetenv_c (String) __asm__ (GOSYM_PREFIX "syscall.unsetenv_c");
|
||||
void unsetenv_c (String) __asm__ (GOSYM_PREFIX "syscall.unsetenv__c");
|
||||
|
||||
void
|
||||
unsetenv_c (String k)
|
||||
|
|
|
@ -440,7 +440,7 @@ void runtime_freedefer(Defer*);
|
|||
|
||||
extern void _cgo_wait_runtime_init_done (void);
|
||||
extern void _cgo_notify_runtime_init_done (void)
|
||||
__asm__ (GOSYM_PREFIX "runtime._cgo_notify_runtime_init_done");
|
||||
__asm__ (GOSYM_PREFIX "runtime.__cgo__notify__runtime__init__done");
|
||||
extern _Bool runtime_iscgo;
|
||||
extern uintptr __go_end __attribute__ ((weak));
|
||||
extern void *getitab(const struct _type *, const struct _type *, _Bool)
|
||||
|
|
|
@ -496,7 +496,8 @@ testname() {
|
|||
localname() {
|
||||
# The package main has been renamed to __main__ when imported.
|
||||
# Adjust its uses.
|
||||
echo $1 | sed 's/^main\./__main__./'
|
||||
# Also demangle underscores.
|
||||
echo $1 | sed 's/^main\./__main__./' | sed 's/__/_/'
|
||||
}
|
||||
|
||||
# Takes a list of tests derived from 'nm' output (whose symbols are mangled)
|
||||
|
@ -504,7 +505,7 @@ localname() {
|
|||
# Example:
|
||||
#
|
||||
# Original symbol: foo/bar/leaf.Mumble
|
||||
# Mangled symbol: foo..z2fbar..z2fleaf.Mumble
|
||||
# Mangled symbol: foo_1fbar_1leaf.Mumble
|
||||
# Returned: leaf.Mumble
|
||||
#
|
||||
symtogo() {
|
||||
|
@ -522,7 +523,7 @@ symtogo() {
|
|||
if expr "$tp" : '^type\.\.' >/dev/null 2>&1; then
|
||||
continue
|
||||
fi
|
||||
s=$(echo "$tp" | sed -e 's/\.\.z2f/%/g' | sed -e 's/.*%//')
|
||||
s=$(echo "$tp" | sed -e 's/_1/%/g' | sed -e 's/.*%//')
|
||||
# Screen out methods (X.Y.Z).
|
||||
if ! expr "$s" : '^[^.]*\.[^.]*$' >/dev/null 2>&1; then
|
||||
continue
|
||||
|
|
Loading…
Add table
Reference in a new issue