0cdde1e7ae
On NetBSD, for backwards compatibility, various libc symbols are renamed to a symbol with a version suffix. For example, this is the (abbreviated) definition of sigaction: int sigaction(...) __asm__ ("__sigaction14") This poses a challenge for libgo, which attempts to link sigaction by way of an "//extern" comment: //extern sigaction func sigaction(...) This results in a reference to the deprecated compatibility symbol "sigaction", rather than the desired "__sigaction14" symbol. This patch introduces a new "//extern-sysinfo" comment to handle this situation. The new mklinknames.awk script scans a package for these comments and outputs a "//go:linkname" directive that links the wrapper to the correct versioned symbol, as determined by parsing the __asm__ annotation on the function's declaration in gen-sysinfo.go. For now, only the following packages are scanned by mklinknames.awk: os os/user runtime syscall gotools/: * Makefile.am (check-runtime): Add runtime_linknames.go to --extrafiles. * Makefile.in: Regenerate. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/265125
47 lines
1.6 KiB
Awk
47 lines
1.6 KiB
Awk
# Copyright 2020 The Go Authors. All rights reserved.
|
|
# Use of this source code is governed by a BSD-style
|
|
# license that can be found in the LICENSE file.
|
|
|
|
# This AWK script reads a Go file with special //extern-sysinfo
|
|
# comments annotating functions which should be linked to libc
|
|
# functions. It generates a Go file containing the appropriate
|
|
# //go:linkname directives.
|
|
#
|
|
# For each annotated function, the script searches gen-sysinfo.go
|
|
# to see if a different assembly name is known for the function.
|
|
# For example, on NetBSD, the timegm symbol is renamed to
|
|
# __timegm50 by an __asm__ annotation on its declaration in time.h.
|
|
|
|
BEGIN {
|
|
print "// Code generated by mklinknames.awk. DO NOT EDIT."
|
|
print ""
|
|
print "package", package
|
|
print ""
|
|
print "import _ \"unsafe\""
|
|
print ""
|
|
}
|
|
|
|
/^\/\/extern-sysinfo/ {
|
|
cfnname = $2
|
|
getline
|
|
if ($1 != "func") {
|
|
printf("mklinknames.awk: error: %s:%d: unattached extern-sysinfo directive\n", FILENAME, FNR) | "cat 1>&2"
|
|
exit 1
|
|
}
|
|
split($2, a, "(")
|
|
gofnname = a[1]
|
|
def = sprintf("grep '^func _%s[ (]' gen-sysinfo.go", cfnname)
|
|
# def looks like one of the following:
|
|
# func _timegm (*_tm) int64 __asm__("__timegm50")
|
|
# func _timegm (*_tm) int64 __asm__("*__timegm50")
|
|
# The goal is to extract "__timegm50".
|
|
if ((def | getline fndef) > 0 && match(fndef, "__asm__\\(\"\\*?")) {
|
|
asmname = substr(fndef, RSTART + RLENGTH)
|
|
asmname = substr(asmname, 0, length(asmname) - 2)
|
|
printf("//go:linkname %s %s\n", gofnname, asmname)
|
|
} else {
|
|
# Assume the asm name is the same as the declared C name.
|
|
printf("//go:linkname %s %s\n", gofnname, cfnname)
|
|
}
|
|
}
|