Skip to content

Commit 663a94f

Browse files
mikesmittydeadprogram
authored andcommitted
feat: enable //go:linkname pragma for globals
1 parent 373ca88 commit 663a94f

File tree

1 file changed

+15
-4
lines changed

1 file changed

+15
-4
lines changed

compiler/symbol.go

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -630,7 +630,7 @@ func (c *compilerContext) addStandardAttributes(llvmFn llvm.Value) {
630630
// linkName is equal to .RelString(nil) on a global and extern is false, but for
631631
// some symbols this is different (due to //go:extern for example).
632632
type globalInfo struct {
633-
linkName string // go:extern
633+
linkName string // go:extern, go:linkname
634634
extern bool // go:extern
635635
align int // go:align
636636
section string // go:section
@@ -715,14 +715,14 @@ func (c *compilerContext) getGlobalInfo(g *ssa.Global) globalInfo {
715715
// Check for //go: pragmas, which may change the link name (among others).
716716
doc := c.astComments[info.linkName]
717717
if doc != nil {
718-
info.parsePragmas(doc)
718+
info.parsePragmas(doc, c, g)
719719
}
720720
return info
721721
}
722722

723723
// Parse //go: pragma comments from the source. In particular, it parses the
724-
// //go:extern pragma on globals.
725-
func (info *globalInfo) parsePragmas(doc *ast.CommentGroup) {
724+
// //go:extern and //go:linkname pragmas on globals.
725+
func (info *globalInfo) parsePragmas(doc *ast.CommentGroup, c *compilerContext, g *ssa.Global) {
726726
for _, comment := range doc.List {
727727
if !strings.HasPrefix(comment.Text, "//go:") {
728728
continue
@@ -743,6 +743,17 @@ func (info *globalInfo) parsePragmas(doc *ast.CommentGroup) {
743743
if len(parts) == 2 {
744744
info.section = parts[1]
745745
}
746+
case "//go:linkname":
747+
if len(parts) != 3 || parts[1] != g.Name() {
748+
continue
749+
}
750+
// Only enable go:linkname when the package imports "unsafe".
751+
// This is a slightly looser requirement than what gc uses: gc
752+
// requires the file to import "unsafe", not the package as a
753+
// whole.
754+
if hasUnsafeImport(g.Pkg.Pkg) {
755+
info.linkName = parts[2]
756+
}
746757
}
747758
}
748759
}

0 commit comments

Comments
 (0)