Skip to content

Commit 13b51af

Browse files
committed
feat: enable //go:linkname pragma for globals
1 parent c3a8bbf commit 13b51af

File tree

3 files changed

+20
-15
lines changed

3 files changed

+20
-15
lines changed

compiler/symbol.go

Lines changed: 15 additions & 12 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
@@ -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
}

monitor.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ func Monitor(executable, port string, config *compileopts.Config) error {
3535
// Use the RTT interface, which is documented (in part) here:
3636
// https://wiki.segger.com/RTT
3737

38-
// Try to find the "machine.rttSerialInstance" symbol, which is the RTT
39-
// control block.
38+
// Try to find the "_SEGGER_RTT" symbol (machine.rttSerialInstance)
39+
// symbol, which is the RTT control block.
4040
file, err := elf.Open(executable)
4141
if err != nil {
4242
return fmt.Errorf("could not open ELF file to determine RTT control block: %w", err)
@@ -48,7 +48,7 @@ func Monitor(executable, port string, config *compileopts.Config) error {
4848
}
4949
var address uint64
5050
for _, symbol := range symbols {
51-
if symbol.Name == "machine.rttSerialInstance" {
51+
if symbol.Name == "_SEGGER_RTT" {
5252
address = symbol.Value
5353
break
5454
}

src/machine/serial-rtt.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import (
1616
)
1717

1818
// This symbol name is known by the compiler, see monitor.go.
19+
//
20+
//go:linkname rttSerialInstance _SEGGER_RTT
1921
var rttSerialInstance rttSerial
2022

2123
var Serial = &rttSerialInstance

0 commit comments

Comments
 (0)