@@ -630,7 +630,7 @@ func (c *compilerContext) addStandardAttributes(llvmFn llvm.Value) {
630
630
// linkName is equal to .RelString(nil) on a global and extern is false, but for
631
631
// some symbols this is different (due to //go:extern for example).
632
632
type globalInfo struct {
633
- linkName string // go:extern
633
+ linkName string // go:extern, go:linkname
634
634
extern bool // go:extern
635
635
align int // go:align
636
636
section string // go:section
@@ -715,14 +715,14 @@ func (c *compilerContext) getGlobalInfo(g *ssa.Global) globalInfo {
715
715
// Check for //go: pragmas, which may change the link name (among others).
716
716
doc := c .astComments [info .linkName ]
717
717
if doc != nil {
718
- info .parsePragmas (doc )
718
+ info .parsePragmas (doc , c , g )
719
719
}
720
720
return info
721
721
}
722
722
723
723
// 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 ) {
726
726
for _ , comment := range doc .List {
727
727
if ! strings .HasPrefix (comment .Text , "//go:" ) {
728
728
continue
@@ -743,6 +743,17 @@ func (info *globalInfo) parsePragmas(doc *ast.CommentGroup) {
743
743
if len (parts ) == 2 {
744
744
info .section = parts [1 ]
745
745
}
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
+ }
746
757
}
747
758
}
748
759
}
0 commit comments