@@ -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
@@ -702,14 +702,6 @@ func (c *compilerContext) getGlobal(g *ssa.Global) llvm.Value {
702702 })
703703 llvmGlobal .AddMetadata (0 , diglobal )
704704 }
705-
706- if info .linkName == "machine.rttSerialInstance" {
707- // Create the symbol alias and make sure neither gets optimized away.
708- alias := llvm .AddAlias (c .mod , llvmType , 0 , llvmGlobal , "_SEGGER_RTT" )
709- alias .SetVisibility (llvm .HiddenVisibility )
710- llvmutil .AppendToGlobal (c .mod , "llvm.used" , alias )
711- llvmutil .AppendToGlobal (c .mod , "llvm.used" , llvmGlobal )
712- }
713705 }
714706 return llvmGlobal
715707}
@@ -723,14 +715,14 @@ func (c *compilerContext) getGlobalInfo(g *ssa.Global) globalInfo {
723715 // Check for //go: pragmas, which may change the link name (among others).
724716 doc := c .astComments [info .linkName ]
725717 if doc != nil {
726- info .parsePragmas (doc )
718+ info .parsePragmas (doc , c , g )
727719 }
728720 return info
729721}
730722
731723// Parse //go: pragma comments from the source. In particular, it parses the
732- // //go:extern pragma on globals.
733- 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 ) {
734726 for _ , comment := range doc .List {
735727 if ! strings .HasPrefix (comment .Text , "//go:" ) {
736728 continue
@@ -751,6 +743,17 @@ func (info *globalInfo) parsePragmas(doc *ast.CommentGroup) {
751743 if len (parts ) == 2 {
752744 info .section = parts [1 ]
753745 }
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+ }
754757 }
755758 }
756759}
0 commit comments