@@ -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).
632632type 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