Alex Markin has uploaded this change for review.
compiler: enable linkname for objects from runtime
Change-Id: I4e94522015b2b1f2c019783797e574fc55127c3f
---
M go/gogo.cc
M go/gogo.h
M go/names.cc
3 files changed, 58 insertions(+), 12 deletions(-)
diff --git a/go/gogo.cc b/go/gogo.cc
index e13df0d..086799f 100644
--- a/go/gogo.cc
+++ b/go/gogo.cc
@@ -2510,7 +2510,8 @@
}
// Add a linkname. This implements the go:linkname compiler directive.
-// We only support this for functions and function declarations.
+// We only support this for functions, function declarations and runtime
+// variables.
void
Gogo::add_linkname(const std::string& go_name, bool is_exported,
@@ -2538,11 +2539,23 @@
else
no->func_declaration_value()->set_asm_name(ext_name);
}
+ else if (no->is_variable())
+ {
+ if (ext_name.find("runtime.") != 0)
+ go_error_at(loc,
+ ("%s is not a runtime varibale; "
+ "%<//go:linkname%> is not supported for non-runtime "
+ "variables"),
+ go_name.c_str());
+ else
+ no->var_value()->set_asm_name(ext_name);
+ }
else
go_error_at(loc,
- ("%s is not a function; "
- "%<//go:linkname%> is only supported for functions"),
- go_name.c_str());
+ ("%s is neither a function or variable; "
+ "%<//go:linkname%> is only supported for functions and "
+ "runtime variables"),
+ go_name.c_str());
}
// Mark all local variables used. This is used when some types of
@@ -8002,13 +8015,16 @@
else if (this->is_global_)
{
Backend_name bname;
- gogo->global_var_backend_name(name, package, &bname);
+ bool is_asm = !this->asm_name_.empty();
+ gogo->global_var_backend_name(is_asm ? this->asm_name_ : name,
+ package, &bname, is_asm);
- bool is_hidden = Gogo::is_hidden_name(name);
- // Hack to export runtime.writeBarrier. FIXME.
- // This is because go:linkname doesn't work on variables.
+ bool is_hidden = !is_asm && Gogo::is_hidden_name(name);
+
+ // Export runtime variables so they could be linked agianst
+ // go:linkname
if (gogo->compiling_runtime()
- && bname.name() == "runtime.writeBarrier")
+ && bname.name().find("runtime.") == 0)
is_hidden = false;
// If an inline body refers to this variable, then it
@@ -8020,7 +8036,7 @@
// can't be treated as a hidden symbol. This case can
// arise when an inlined function refers to a
// package-scope unexported variable.
- if (package != NULL)
+ if (package != NULL || is_asm)
is_hidden = false;
unsigned int flags = 0;
diff --git a/go/gogo.h b/go/gogo.h
index 2ee0fda..398f638 100644
--- a/go/gogo.h
+++ b/go/gogo.h
@@ -1020,7 +1020,7 @@
// Get the backend name to use for a global variable.
void
global_var_backend_name(const std::string& go_name, const Package*,
- Backend_name*);
+ Backend_name*, bool is_asm = false);
// 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
@@ -2366,6 +2366,16 @@
import_var(Import*, std::string* pname, Package** pkg, bool* is_exported,
Type** ptype);
+ // Return the assembler name.
+ const std::string&
+ asm_name() const
+ { return this->asm_name_; }
+
+ // Set the assembler name.
+ void
+ set_asm_name(const std::string& asm_name)
+ { this->asm_name_ = asm_name; }
+
private:
// The type of a tuple.
Type*
@@ -2379,6 +2389,10 @@
Type*
type_from_chan_element(Expression*, bool) const;
+ // The assembler name: this is the name that will be put in the object file.
+ // Set by the go:linkname compiler directive. This is normally empty.
+ std::string asm_name_;
+
// The variable's type. This may be NULL if the type is set from
// the expression.
Type* type_;
diff --git a/go/names.cc b/go/names.cc
index dac7f20..ceb6a55 100644
--- a/go/names.cc
+++ b/go/names.cc
@@ -366,8 +366,15 @@
void
Gogo::global_var_backend_name(const std::string& go_name,
const Package* package,
- Backend_name* bname)
+ Backend_name* bname,
+ bool is_asm)
{
+ if (is_asm)
+ {
+ bname->set_asm_name(go_name);
+ return;
+ }
+
if (package == NULL)
bname->add(this->pkgpath());
else
To view, visit change 415694. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Alex Markin.
2 comments:
Patchset:
What is the goal here? Is there some associated issue?
We don't support go:linkname for variables because we don't know whether it is a variable reference or a variable definition. I guess we could assume that for runtime it is always a reference?
File go/gogo.h:
Patch Set #1, Line 1023: Backend_name*, bool is_asm = false);
In this code base we normally avoid default values.
To view, visit change 415694. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Ian Lance Taylor.
1 comment:
Patchset:
There is no issue in the github tracker but our project uses few dozens linknames. We want our project to be build with gollvm as well.
I guess we could assume that for runtime it is always a reference?
Not sure I understood you right but if we have only a variable definition we will just get an error while linking.
So this patch does not breaks anything but just adds an unportable feature.
To view, visit change 415694. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Alex Markin.
1 comment:
Patchset:
There is no issue in the github tracker but our project uses few dozens linknames. […]
How do you use go:linkname?
Since the gofrontend code uses the system linker, it must define a variable in a single package. All other packages must use a reference to the variable. And there must be one definition of the variable, not zero.
So if we see
//go:linkname pkg.Var
var Var int
we need to know whether that is a definition of the variable or a reference to the variable. Unfortunately, the //go:linkname directive doesn't tell us which it is.
To view, visit change 415694. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Ian Lance Taylor.
1 comment:
Patchset:
How do you use go:linkname?
Some typical example:
//go:linkname memstats runtime.memstats
var memstats struct {
Alloc int64
// other fields
}
// ...
println(memstats.Alloc)
About your example I can say that while we apply to the variables in system packages like runtime we can say that linkname should generate a reference to a variable and we can control it.
To view, visit change 415694. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Ian Lance Taylor.
Alex Markin uploaded patch set #2 to this change.
compiler: enable linkname for objects from runtime
Change-Id: I4e94522015b2b1f2c019783797e574fc55127c3f
---
M go/gogo.cc
M go/gogo.h
M go/names.cc
3 files changed, 58 insertions(+), 12 deletions(-)
To view, visit change 415694. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Ian Lance Taylor.
1 comment:
File go/gogo.h:
Patch Set #1, Line 1023: Backend_name*, bool is_asm = false);
In this code base we normally avoid default values.
Done
To view, visit change 415694. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Alex Markin.
1 comment:
Patchset:
> How do you use go:linkname? […]
Thanks. That kind of code is not supported by either the gc compiler or the gofrontend compiler. It may work, but there is no promise that it will continue to work.
I don't mind figuring out a general way to fix go:linkname for gofrontend, but I don't think this is the right approach. Thanks.
To view, visit change 415694. To unsubscribe, or for help writing mail filters, visit settings.
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |